CLOUDSTACK-10129: UX improvements and event timeline

- Fixes timezone issue where dates show up as nvalid in UI
- Introduces new event timeline listing/filtering of events
- Several UI improvements to add columns in list views
- Bulk operations support in instance list view to shutdown and destroy
  multiple-selected VMs (limitation: after operation, redundant entries
  may show up in the list view, refreshing VM list view fixes that)
- Align table thead/tbody to avoid splitting of tables

Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com>
This commit is contained in:
Rohit Yadav 2017-11-28 19:25:09 +05:30
parent d0005d8353
commit 0102e8593d
17 changed files with 413 additions and 167 deletions

View File

@ -205,6 +205,7 @@ public class ApiConstants {
public static final String OUTOFBANDMANAGEMENT_POWERSTATE = "outofbandmanagementpowerstate"; public static final String OUTOFBANDMANAGEMENT_POWERSTATE = "outofbandmanagementpowerstate";
public static final String OUTOFBANDMANAGEMENT_ENABLED = "outofbandmanagementenabled"; public static final String OUTOFBANDMANAGEMENT_ENABLED = "outofbandmanagementenabled";
public static final String PARAMS = "params"; public static final String PARAMS = "params";
public static final String PARENT_ID = "parentid";
public static final String PARENT_DOMAIN_ID = "parentdomainid"; public static final String PARENT_DOMAIN_ID = "parentdomainid";
public static final String PASSWORD = "password"; public static final String PASSWORD = "password";
public static final String SHOULD_UPDATE_PASSWORD = "update_passwd_on_host"; public static final String SHOULD_UPDATE_PASSWORD = "update_passwd_on_host";
@ -274,6 +275,7 @@ public class ApiConstants {
public static final String SNAPSHOT_QUIESCEVM = "quiescevm"; public static final String SNAPSHOT_QUIESCEVM = "quiescevm";
public static final String SOURCE_ZONE_ID = "sourcezoneid"; public static final String SOURCE_ZONE_ID = "sourcezoneid";
public static final String START_DATE = "startdate"; public static final String START_DATE = "startdate";
public static final String START_ID = "startid";
public static final String START_IP = "startip"; public static final String START_IP = "startip";
public static final String START_IPV6 = "startipv6"; public static final String START_IPV6 = "startipv6";
public static final String START_PORT = "startport"; public static final String START_PORT = "startport";

View File

@ -65,6 +65,9 @@ public class ListEventsCmd extends BaseListProjectAndAccountResourcesCmd {
@Parameter(name = ApiConstants.TYPE, type = CommandType.STRING, description = "the event type (see event types)") @Parameter(name = ApiConstants.TYPE, type = CommandType.STRING, description = "the event type (see event types)")
private String type; private String type;
@Parameter(name = ApiConstants.START_ID, type = CommandType.UUID, entityType = EventResponse.class, description = "the parent/start ID of the event, when provided this will list all the events with the start/parent ID including the parent event")
private Long startId;
///////////////////////////////////////////////////// /////////////////////////////////////////////////////
/////////////////// Accessors /////////////////////// /////////////////// Accessors ///////////////////////
///////////////////////////////////////////////////// /////////////////////////////////////////////////////
@ -97,6 +100,10 @@ public class ListEventsCmd extends BaseListProjectAndAccountResourcesCmd {
return type; return type;
} }
public Long getStartId() {
return startId;
}
///////////////////////////////////////////////////// /////////////////////////////////////////////////////
/////////////// API Implementation/////////////////// /////////////// API Implementation///////////////////
///////////////////////////////////////////////////// /////////////////////////////////////////////////////

View File

@ -78,7 +78,7 @@ public class EventResponse extends BaseResponse implements ControlledViewEntityR
@Param(description = "the state of the event") @Param(description = "the state of the event")
private Event.State state; private Event.State state;
@SerializedName("parentid") @SerializedName(ApiConstants.PARENT_ID)
@Param(description = "whether the event is parented") @Param(description = "whether the event is parented")
private String parentId; private String parentId;

View File

@ -33,6 +33,7 @@ import org.apache.cloudstack.api.InternalIdentity;
import com.cloud.utils.db.Encrypt; import com.cloud.utils.db.Encrypt;
import com.cloud.utils.db.GenericDao; import com.cloud.utils.db.GenericDao;
import com.google.common.base.Strings;
@Entity @Entity
@Table(name = "user") @Table(name = "user")
@ -257,6 +258,9 @@ public class UserAccountVO implements UserAccount, InternalIdentity {
@Override @Override
public String getTimezone() { public String getTimezone() {
if (Strings.isNullOrEmpty(timezone)) {
return "UTC";
}
return timezone; return timezone;
} }

View File

@ -34,6 +34,7 @@ import org.apache.cloudstack.api.InternalIdentity;
import com.cloud.user.Account.State; import com.cloud.user.Account.State;
import com.cloud.utils.db.Encrypt; import com.cloud.utils.db.Encrypt;
import com.cloud.utils.db.GenericDao; import com.cloud.utils.db.GenericDao;
import com.google.common.base.Strings;
/** /**
* A bean representing a user * A bean representing a user
@ -233,6 +234,9 @@ public class UserVO implements User, Identity, InternalIdentity {
@Override @Override
public String getTimezone() { public String getTimezone() {
if (Strings.isNullOrEmpty(timezone)) {
return "UTC";
}
return timezone; return timezone;
} }

View File

@ -520,6 +520,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
String keyword = cmd.getKeyword(); String keyword = cmd.getKeyword();
Integer entryTime = cmd.getEntryTime(); Integer entryTime = cmd.getEntryTime();
Integer duration = cmd.getDuration(); Integer duration = cmd.getDuration();
Long startId = cmd.getStartId();
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>( Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(
cmd.getDomainId(), cmd.isRecursive(), null); cmd.getDomainId(), cmd.isRecursive(), null);
@ -542,7 +543,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
sb.and("createDateG", sb.entity().getCreateDate(), SearchCriteria.Op.GTEQ); sb.and("createDateG", sb.entity().getCreateDate(), SearchCriteria.Op.GTEQ);
sb.and("createDateL", sb.entity().getCreateDate(), SearchCriteria.Op.LTEQ); sb.and("createDateL", sb.entity().getCreateDate(), SearchCriteria.Op.LTEQ);
sb.and("state", sb.entity().getState(), SearchCriteria.Op.NEQ); sb.and("state", sb.entity().getState(), SearchCriteria.Op.NEQ);
sb.and("startId", sb.entity().getStartId(), SearchCriteria.Op.EQ); sb.or("startId", sb.entity().getStartId(), SearchCriteria.Op.EQ);
sb.and("createDate", sb.entity().getCreateDate(), SearchCriteria.Op.BETWEEN); sb.and("createDate", sb.entity().getCreateDate(), SearchCriteria.Op.BETWEEN);
sb.and("displayEvent", sb.entity().getDisplay(), SearchCriteria.Op.EQ); sb.and("displayEvent", sb.entity().getDisplay(), SearchCriteria.Op.EQ);
sb.and("archived", sb.entity().getArchived(), SearchCriteria.Op.EQ); sb.and("archived", sb.entity().getArchived(), SearchCriteria.Op.EQ);
@ -561,6 +562,13 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
sc.setParameters("id", id); sc.setParameters("id", id);
} }
if (startId != null) {
sc.setParameters("startId", startId);
if (id == null) {
sc.setParameters("id", startId);
}
}
if (keyword != null) { if (keyword != null) {
SearchCriteria<EventJoinVO> ssc = _eventJoinDao.createSearchCriteria(); SearchCriteria<EventJoinVO> ssc = _eventJoinDao.createSearchCriteria();
ssc.addOr("type", SearchCriteria.Op.LIKE, "%" + keyword + "%"); ssc.addOr("type", SearchCriteria.Op.LIKE, "%" + keyword + "%");

View File

@ -96,7 +96,7 @@ a:hover {
/*Table*/ /*Table*/
table { table {
width: 940px; width: 955px;
max-width: 977px; max-width: 977px;
margin: 15px 15px 12px 12px; margin: 15px 15px 12px 12px;
font-size: 13px; font-size: 13px;
@ -1307,7 +1307,6 @@ div.panel div.list-view {
div.panel div.list-view div.data-table table { div.panel div.list-view div.data-table table {
width: 955px; width: 955px;
margin-top: 44px;
} }
.detail-view div.list-view div.data-table table { .detail-view div.list-view div.data-table table {

View File

@ -558,6 +558,7 @@ var dictionary = {"ICMP.code":"ICMP Code",
"label.console.proxy.vm":"Console Proxy VM", "label.console.proxy.vm":"Console Proxy VM",
"label.continue":"Continue", "label.continue":"Continue",
"label.continue.basic.install":"Continue with basic installation", "label.continue.basic.install":"Continue with basic installation",
"label.control.ip":"Control IP",
"label.copying.iso":"Copying ISO", "label.copying.iso":"Copying ISO",
"label.corrections.saved":"Corrections saved", "label.corrections.saved":"Corrections saved",
"label.counter":"Counter", "label.counter":"Counter",
@ -751,6 +752,7 @@ var dictionary = {"ICMP.code":"ICMP Code",
"label.event":"Event", "label.event":"Event",
"label.event.archived":"Event Archived", "label.event.archived":"Event Archived",
"label.event.deleted":"Event Deleted", "label.event.deleted":"Event Deleted",
"label.event.timeline":"Event Timeline",
"label.every":"Every", "label.every":"Every",
"label.example":"Example", "label.example":"Example",
"label.expunge":"Expunge", "label.expunge":"Expunge",
@ -995,6 +997,7 @@ var dictionary = {"ICMP.code":"ICMP Code",
"label.manage":"Manage", "label.manage":"Manage",
"label.manage.resources":"Manage Resources", "label.manage.resources":"Manage Resources",
"label.managed":"Managed", "label.managed":"Managed",
"label.managed.state":"Managed State",
"label.management":"Management", "label.management":"Management",
"label.management.ips":"Management IP Addresses", "label.management.ips":"Management IP Addresses",
"label.management.server":"Management Server", "label.management.server":"Management Server",

View File

@ -46,12 +46,12 @@
label: 'label.type', label: 'label.type',
truncate: true truncate: true
}, },
domain: {
label: 'label.domain'
},
account: { account: {
label: 'label.account' label: 'label.account'
}, },
domain: {
label: 'label.domain'
},
created: { created: {
label: 'label.date', label: 'label.date',
converter: cloudStack.converters.toLocalDate converter: cloudStack.converters.toLocalDate
@ -338,6 +338,14 @@
var data = {}; var data = {};
listViewDataProvider(args, data); listViewDataProvider(args, data);
if ("events" in args.context) {
var startId = args.context.events[0].parentid;
if (!startId) {
startId = args.context.events[0].id;
}
data.startid = startId;
}
$.ajax({ $.ajax({
url: createURL('listEvents'), url: createURL('listEvents'),
data: data, data: data,
@ -357,8 +365,12 @@
}, },
detailView: { detailView: {
name: 'label.details', name: 'label.details',
actions: { viewAll: {
path: 'events',
label: 'label.event.timeline',
},
actions: {
// Remove single event // Remove single event
remove: { remove: {
label: 'label.delete', label: 'label.delete',

View File

@ -17,6 +17,153 @@
(function($, cloudStack) { (function($, cloudStack) {
var vmMigrationHostObjs, ostypeObjs; var vmMigrationHostObjs, ostypeObjs;
var vmStopAction = function(args) {
var action = {
messages: {
confirm: function(args) {
return 'message.action.stop.instance';
},
notification: function(args) {
return 'label.action.stop.instance';
}
},
label: 'label.action.stop.instance',
compactLabel: 'label.stop',
addRow: 'false',
createForm: {
title: 'notification.stop.instance',
desc: 'message.action.stop.instance',
fields: {
forced: {
label: 'force.stop',
isBoolean: true,
isChecked: false
}
}
},
action: function(args) {
var instances = args.context.instances;
$(instances).map(function(index, instance) {
var data = {
id: instance.id,
forced: (args.data.forced == "on")
};
$.ajax({
url: createURL("stopVirtualMachine"),
data: data,
dataType: "json",
success: function(json) {
var jid = json.stopvirtualmachineresponse.jobid;
args.response.success({
_custom: {
jobId: jid,
getUpdatedItem: function(json) {
return $.extend(json.queryasyncjobresultresponse.jobresult.virtualmachine, { hostid: null });
},
getActionFilter: function() {
return vmActionfilter;
}
}
});
},
error: function(json) {
args.response.error(parseXMLHttpResponse(json));
}
});
});
},
notification: {
poll: pollAsyncJobResult
}
};
if (args && args.listView) {
$.extend(action, {
isHeader: true,
isMultiSelectAction: true
});
}
return action;
};
var vmDestroyAction = function(args) {
var action = {
messages: {
notification: function(args) {
return 'label.action.destroy.instance';
}
},
label: 'label.action.destroy.instance',
compactLabel: 'label.destroy',
addRow: 'false',
createForm: {
title: 'label.action.destroy.instance',
desc: 'label.action.destroy.instance',
isWarning: true,
preFilter: function(args) {
if (! g_allowUserExpungeRecoverVm) {
args.$form.find('.form-item[rel=expunge]').hide();
}
},
fields: {
expunge: {
label: 'label.expunge',
isBoolean: true,
isChecked: false
}
}
},
action: function(args) {
var instances = args.context.instances;
$(instances).map(function(index, instance) {
var data = {
id: instance.id
};
if (args.data.expunge == 'on') {
$.extend(data, {
expunge: true
});
}
$.ajax({
url: createURL('destroyVirtualMachine'),
data: data,
success: function(json) {
var jid = json.destroyvirtualmachineresponse.jobid;
args.response.success({
_custom: {
jobId: jid,
getUpdatedItem: function(json) {
if ('virtualmachine' in json.queryasyncjobresultresponse.jobresult) //destroy without expunge
return json.queryasyncjobresultresponse.jobresult.virtualmachine;
else //destroy with expunge
return { 'toRemove': true };
},
getActionFilter: function() {
return vmActionfilter;
}
}
});
}
});
});
},
notification: {
poll: pollAsyncJobResult
}
};
if (args && args.listView) {
$.extend(action, {
isHeader: true,
isMultiSelectAction: true
});
}
return action;
};
var vmSnapshotAction = function(args) { var vmSnapshotAction = function(args) {
var action = { var action = {
messages: { messages: {
@ -162,6 +309,7 @@
var hiddenFields = []; var hiddenFields = [];
if (!isAdmin()) { if (!isAdmin()) {
hiddenFields.push('instancename'); hiddenFields.push('instancename');
hiddenFields.push('account');
} }
return hiddenFields; return hiddenFields;
}, },
@ -180,16 +328,26 @@
ipaddress: { ipaddress: {
label: 'label.ip.address' label: 'label.ip.address'
}, },
account: {
label: 'label.account'
},
zonename: { zonename: {
label: 'label.zone.name' label: 'label.zone.name'
}, },
state: { state: {
label: 'label.state', label: 'label.metrics.state',
converter: function (str) {
// For localization
return str;
},
indicator: { indicator: {
'Running': 'on', 'Running': 'on',
'Stopped': 'off', 'Stopped': 'off',
'Error': 'off',
'Destroyed': 'off', 'Destroyed': 'off',
'Error': 'off' 'Expunging': 'off',
'Stopping': 'warning',
'Shutdowned': 'warning'
} }
} }
}, },
@ -304,6 +462,8 @@
poll: pollAsyncJobResult poll: pollAsyncJobResult
} }
}, },
stop: vmStopAction({ listView: true}),
destroy: vmDestroyAction({ listView: true }),
snapshot: vmSnapshotAction({ listView: true }), snapshot: vmSnapshotAction({ listView: true }),
viewMetrics: { viewMetrics: {
label: 'label.metrics', label: 'label.metrics',
@ -683,55 +843,7 @@
poll: pollAsyncJobResult poll: pollAsyncJobResult
} }
}, },
stop: { stop: vmStopAction(),
label: 'label.action.stop.instance',
compactLabel: 'label.stop',
createForm: {
title: 'notification.stop.instance',
desc: 'message.action.stop.instance',
fields: {
forced: {
label: 'force.stop',
isBoolean: true,
isChecked: false
}
}
},
action: function(args) {
var array1 = [];
array1.push("&forced=" + (args.data.forced == "on"));
$.ajax({
url: createURL("stopVirtualMachine&id=" + args.context.instances[0].id + array1.join("")),
dataType: "json",
async: true,
success: function(json) {
var jid = json.stopvirtualmachineresponse.jobid;
args.response.success({
_custom: {
jobId: jid,
getUpdatedItem: function(json) {
return $.extend(json.queryasyncjobresultresponse.jobresult.virtualmachine, { hostid: null });
},
getActionFilter: function() {
return vmActionfilter;
}
}
});
}
});
},
messages: {
confirm: function(args) {
return 'message.action.stop.instance';
},
notification: function(args) {
return 'label.action.stop.instance';
}
},
notification: {
poll: pollAsyncJobResult
}
},
restart: { restart: {
label: 'label.action.reboot.instance', label: 'label.action.reboot.instance',
compactLabel: 'label.reboot', compactLabel: 'label.reboot',
@ -775,66 +887,7 @@
} }
}, },
snapshot: vmSnapshotAction(), snapshot: vmSnapshotAction(),
destroy: { destroy: vmDestroyAction(),
label: 'label.action.destroy.instance',
compactLabel: 'label.destroy',
createForm: {
title: 'label.action.destroy.instance',
desc: 'label.action.destroy.instance',
isWarning: true,
preFilter: function(args) {
if (! g_allowUserExpungeRecoverVm) {
args.$form.find('.form-item[rel=expunge]').hide();
}
},
fields: {
expunge: {
label: 'label.expunge',
isBoolean: true,
isChecked: false
}
}
},
messages: {
notification: function(args) {
return 'label.action.destroy.instance';
}
},
action: function(args) {
var data = {
id: args.context.instances[0].id
};
if (args.data.expunge == 'on') {
$.extend(data, {
expunge: true
});
}
$.ajax({
url: createURL('destroyVirtualMachine'),
data: data,
success: function(json) {
var jid = json.destroyvirtualmachineresponse.jobid;
args.response.success({
_custom: {
jobId: jid,
getUpdatedItem: function(json) {
if ('virtualmachine' in json.queryasyncjobresultresponse.jobresult) //destroy without expunge
return json.queryasyncjobresultresponse.jobresult.virtualmachine;
else //destroy with expunge
return { 'toRemove': true };
},
getActionFilter: function() {
return vmActionfilter;
}
}
});
}
});
},
notification: {
poll: pollAsyncJobResult
}
},
expunge: { expunge: {
label: 'label.action.expunge.instance', label: 'label.action.expunge.instance',
compactLabel: 'label.expunge', compactLabel: 'label.expunge',

View File

@ -293,8 +293,6 @@
'Disconnected': 'off', 'Disconnected': 'off',
'Removed': 'off', 'Removed': 'off',
'Error': 'off', 'Error': 'off',
'Connecting': 'transition',
'Rebalancing': 'transition',
'Alert': 'warning' 'Alert': 'warning'
}, },
compact: true compact: true
@ -448,9 +446,7 @@
'Error': 'off', 'Error': 'off',
'Destroyed': 'off', 'Destroyed': 'off',
'Expunging': 'off', 'Expunging': 'off',
'Stopping': 'transition', 'Stopping': 'warning',
'Starting': 'transition',
'Migrating': 'transition',
'Shutdowned': 'warning' 'Shutdowned': 'warning'
}, },
compact: true compact: true
@ -560,13 +556,12 @@
return str; return str;
}, },
indicator: { indicator: {
'Allocated': 'transition', 'Allocated': 'on',
'Creating': 'transition',
'Ready': 'on', 'Ready': 'on',
'Destroy': 'off', 'Destroy': 'off',
'Expunging': 'off', 'Expunging': 'off',
'Migrating': 'warning', 'Migrating': 'warning',
'UploadOp': 'transition', 'UploadOp': 'warning',
'Snapshotting': 'warning', 'Snapshotting': 'warning',
}, },
compact: true compact: true
@ -651,7 +646,7 @@
'Down': 'off', 'Down': 'off',
'Removed': 'off', 'Removed': 'off',
'ErrorInMaintenance': 'off', 'ErrorInMaintenance': 'off',
'PrepareForMaintenance': 'transition', 'PrepareForMaintenance': 'warning',
'CancelMaintenance': 'warning', 'CancelMaintenance': 'warning',
'Maintenance': 'warning', 'Maintenance': 'warning',
}, },

View File

@ -808,13 +808,16 @@
}, },
id: 'networks', id: 'networks',
preFilter: function(args) {
if (isAdmin() || isDomainAdmin()) {
return []
}
return ['account']
},
fields: { fields: {
name: { name: {
label: 'label.name' label: 'label.name'
}, },
account: {
label: 'label.account'
},
type: { type: {
label: 'label.type' label: 'label.type'
}, },
@ -823,6 +826,27 @@
}, },
ip6cidr: { ip6cidr: {
label: 'label.ipv6.CIDR' label: 'label.ipv6.CIDR'
},
account: {
label: 'label.account'
},
zonename: {
label: 'label.zone'
},
state: {
converter: function(str) {
// For localization
return str;
},
label: 'label.state',
indicator: {
'Allocated': 'on',
'Released': 'off',
'Destroy': 'off',
'Shutdown': 'off',
'Setup': 'warning',
'Implemented': 'on'
}
} }
}, },
@ -1635,11 +1659,14 @@
networkid: args.context.networks[0].id networkid: args.context.networks[0].id
}, },
dataType: 'json', dataType: 'json',
async: true, async: false,
success: function(json) { success: function(json) {
var response = json.listegressfirewallrulesresponse.firewallrule ? var response = json.listegressfirewallrulesresponse.firewallrule ?
json.listegressfirewallrulesresponse.firewallrule : []; json.listegressfirewallrulesresponse.firewallrule : [];
if (response.length > 0) {
isConfigRulesMsgShown = true;
}
args.response.success({ args.response.success({
data: $.map(response, function(rule) { data: $.map(response, function(rule) {
if (rule.protocol == 'all') { if (rule.protocol == 'all') {
@ -1899,6 +1926,12 @@
listView: { listView: {
id: 'ipAddresses', id: 'ipAddresses',
label: 'label.ips', label: 'label.ips',
preFilter: function(args) {
if (isAdmin()) {
return ['account']
}
return []
},
fields: { fields: {
ipaddress: { ipaddress: {
label: 'label.ips', label: 'label.ips',
@ -1910,12 +1943,18 @@
return text; return text;
} }
}, },
zonename: { associatednetworkname: {
label: 'label.zone' label: 'label.network'
}, },
virtualmachinedisplayname: { virtualmachinedisplayname: {
label: 'label.vm.name' label: 'label.vm.name'
}, },
account: {
label: 'label.account'
},
zonename: {
label: 'label.zone'
},
state: { state: {
converter: function(str) { converter: function(str) {
// For localization // For localization

View File

@ -1285,7 +1285,7 @@ cloudStack.converters = {
var disconnected = new Date(); var disconnected = new Date();
disconnected.setISO8601(UtcDate); disconnected.setISO8601(UtcDate);
if (g_timezoneoffset != null) { if (g_timezoneoffset != null && g_timezoneoffset != "null") {
localDate = disconnected.getTimePlusTimezoneOffset(g_timezoneoffset); localDate = disconnected.getTimePlusTimezoneOffset(g_timezoneoffset);
} else { } else {
var browserDate = new Date(); var browserDate = new Date();

View File

@ -36,8 +36,10 @@
label: 'label.volumes', label: 'label.volumes',
preFilter: function(args) { preFilter: function(args) {
var hiddenFields = []; var hiddenFields = [];
if (isAdmin() != true) if (isAdmin() != true) {
hiddenFields.push('hypervisor'); hiddenFields.push('hypervisor');
hiddenFields.push('account');
}
return hiddenFields; return hiddenFields;
}, },
fields: { fields: {
@ -47,11 +49,33 @@
type: { type: {
label: 'label.type' label: 'label.type'
}, },
vmdisplayname: {
label: 'label.vm.display.name'
},
hypervisor: { hypervisor: {
label: 'label.hypervisor' label: 'label.hypervisor'
}, },
vmdisplayname: { account: {
label: 'label.vm.display.name' label: 'label.account'
},
zonename: {
label: 'label.zone'
},
state: {
label: 'label.metrics.state',
converter: function (str) {
// For localization
return str;
},
indicator: {
'Allocated': 'on',
'Ready': 'on',
'Destroy': 'off',
'Expunging': 'off',
'Migrating': 'warning',
'UploadOp': 'warning',
'Snapshotting': 'warning',
}
} }
}, },

View File

@ -39,7 +39,7 @@
router.guestnetworkname = router.vpcname; router.guestnetworkname = router.vpcname;
} }
if ("isredundantrouter" in router && router.isredundantrouter) { if (router.isredundantrouter) {
router.guestnetworkname = router.guestnetworkname + " (" + router.redundantstate + ")"; router.guestnetworkname = router.guestnetworkname + " (" + router.redundantstate + ")";
} }
@ -2180,6 +2180,12 @@
}, },
isolationmethods: { isolationmethods: {
label: 'label.isolation.method' label: 'label.isolation.method'
},
vlan: {
label: 'label.vlan'
},
broadcastdomainrange: {
label: 'label.broadcast.domain.range'
} }
}, },
@ -9205,6 +9211,14 @@
data: data, data: data,
success: function (json) { success: function (json) {
var systemvmObjs = json.listsystemvmsresponse.systemvm; var systemvmObjs = json.listsystemvmsresponse.systemvm;
$(systemvmObjs).each(function(idx, item) {
var controlIp = item.linklocalip;
if (item.hypervisor == "VMware") {
var controlIp = item.privateip;
}
item.controlip = controlIp;
});
if (systemvmObjs != undefined) { if (systemvmObjs != undefined) {
$.ajax({ $.ajax({
url: createURL('listHosts'), url: createURL('listHosts'),
@ -9585,16 +9599,19 @@
label: 'label.name' label: 'label.name'
}, },
publicip: { publicip: {
label: 'label.public.ip' label: 'label.ip'
}, },
account: { routerType: {
label: 'label.account' label: 'label.type'
}, },
guestnetworkname: { guestnetworkname: {
label: 'label.network' label: 'label.network'
}, },
routerType: { account: {
label: 'label.type' label: 'label.account'
},
hostname: {
label: 'label.host'
}, },
state: { state: {
converter: function (str) { converter: function (str) {
@ -10976,6 +10993,12 @@
return args; return args;
} }
}, },
controlip: {
label: 'label.control.ip'
},
hostname: {
label: 'label.host'
},
zonename: { zonename: {
label: 'label.zone' label: 'label.zone'
}, },
@ -13293,12 +13316,19 @@
netmask: { netmask: {
label: 'label.netmask' label: 'label.netmask'
}, },
zonename: {
label: 'label.zone'
},
allocationstate: { allocationstate: {
converter: function (str) { converter: function (str) {
// For localization // For localization
return str; return str;
}, },
label: 'label.allocation.state' label: 'label.allocation.state',
indicator: {
'Enabled': 'on',
'Disabled': 'off'
}
} }
}, },
@ -13934,23 +13964,27 @@
name: { name: {
label: 'label.name' label: 'label.name'
}, },
podname: {
label: 'label.pod'
},
hypervisortype: { hypervisortype: {
label: 'label.hypervisor' label: 'label.hypervisor'
}, },
//allocationstate: { label: 'label.allocation.state' }, zonename: {
//managedstate: { label: 'Managed State' }, label: 'label.zone'
},
podname: {
label: 'label.pod'
},
managedstate: {
label: 'label.managed.state'
},
allocationstate: { allocationstate: {
converter: function (str) { converter: function (str) {
// For localization // For localization
return str; return str;
}, },
label: 'label.state', label: 'label.allocation.state',
indicator: { indicator: {
'Enabled': 'on', 'Enabled': 'on',
'Destroyed': 'off' 'Disabled': 'off'
} }
} }
}, },
@ -15487,15 +15521,26 @@
name: { name: {
label: 'label.name' label: 'label.name'
}, },
ipaddress: {
label: 'label.ip.address'
},
hypervisor: {
label: 'label.hypervisor'
},
zonename: { zonename: {
label: 'label.zone' label: 'label.zone'
}, },
podname: {
label: 'label.pod'
},
clustername: { clustername: {
label: 'label.cluster' label: 'label.cluster'
}, },
resourcestate: {
label: 'label.resource.state',
indicator: {
'Enabled': 'on',
'Disabled': 'off',
'Maintenance': 'warning'
}
},
state: { state: {
label: 'label.state', label: 'label.state',
indicator: { indicator: {
@ -17497,12 +17542,34 @@
label: 'label.path', label: 'label.path',
truncate: true truncate: true
}, },
type: {
label: 'label.type'
},
scope: {
label: 'label.scope'
},
clustername: { clustername: {
label: 'label.cluster', label: 'label.cluster',
truncate: true truncate: true
}, },
scope: { zonename: {
label: 'label.scope' label: 'label.zone'
},
state: {
label: 'label.state',
converter: function (str) {
// For localization
return str;
},
indicator: {
'Up': 'on',
'Down': 'off',
'Removed': 'off',
'ErrorInMaintenance': 'off',
'PrepareForMaintenance': 'warning',
'CancelMaintenance': 'warning',
'Maintenance': 'warning',
}
} }
}, },
@ -19492,8 +19559,17 @@
name: { name: {
label: 'label.name' label: 'label.name'
}, },
url: {
label: 'label.url'
},
protocol: { protocol: {
label: 'label.protocol' label: 'label.protocol'
},
scope: {
label: 'label.scope'
},
zonename: {
label: 'label.zone'
} }
}, },

View File

@ -55,12 +55,24 @@
label: 'label.community' label: 'label.community'
} }
}, },
preFilter: function() {
if (isAdmin()||isDomainAdmin()) {
return []
}
return ['account']
},
fields: { fields: {
name: { name: {
label: 'label.name' label: 'label.name'
}, },
hypervisor: { hypervisor: {
label: 'label.hypervisor' label: 'label.hypervisor'
},
ostypename: {
label: 'label.os.type'
},
account: {
label: 'label.account'
} }
}, },
@ -2038,9 +2050,21 @@
label: 'label.community' label: 'label.community'
} }
}, },
preFilter: function() {
if (isAdmin()||isDomainAdmin()) {
return []
}
return ['account']
},
fields: { fields: {
name: { name: {
label: 'label.name' label: 'label.name'
},
ostypename: {
label: 'label.os.type'
},
account: {
label: 'label.account'
} }
}, },
@ -2347,7 +2371,10 @@
id: item.id, id: item.id,
name: item.name, name: item.name,
description: item.description, description: item.description,
ostypename: item.ostypename,
ostypeid: item.ostypeid, ostypeid: item.ostypeid,
account: item.account,
domain: item.domain,
zones: item.zonename, zones: item.zonename,
zoneids: [item.zoneid] zoneids: [item.zoneid]
}; };

View File

@ -78,19 +78,12 @@
return true; return true;
}; };
var splitTable = function() { var reattachTable = function() {
var $mainContainer = $('<div>') var $mainContainer = $('<div>')
.addClass('data-table') .addClass('data-table')
.appendTo($table.parent()) .appendTo($table.parent())
.append( .append($table.detach()
$table.detach()
); );
$table = $mainContainer;
var $theadContainer = $('<div>').addClass('fixed-header').prependTo($table);
var $theadTable = $('<table>').appendTo($theadContainer).attr('nowrap', 'nowrap');
var $thead = $table.find('thead').detach().appendTo($theadTable);
return $thead;
}; };
/** /**
@ -289,7 +282,7 @@
var init = function() { var init = function() {
var noSelect = options && options.noSelect == true ? true : false; var noSelect = options && options.noSelect == true ? true : false;
if (!$table.closest('div.data-table').size() && !$table.hasClass('no-split')) { if (!$table.closest('div.data-table').size() && !$table.hasClass('no-split')) {
splitTable(); reattachTable();
$table.find('tbody').closest('table').addClass('body'); $table.find('tbody').closest('table').addClass('body');
} }