Merge remote-tracking branch 'origin/4.15'

Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com>
This commit is contained in:
Rohit Yadav 2021-03-29 16:34:22 +05:30
commit c1a02e1697
115 changed files with 399 additions and 120 deletions

View File

@ -42,6 +42,4 @@ public interface ApiServerService {
public String handleRequest(Map<String, Object[]> params, String responseType, StringBuilder auditTrailSb) throws ServerApiException;
public Class<?> getCmdClass(String cmdName);
public boolean isValidApiName(String apiName);
}

View File

@ -94,9 +94,6 @@ public class ImportRoleCmd extends RoleCmd {
if (Strings.isNullOrEmpty(rule)) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Empty rule provided in rules param");
}
if (!rule.contains("*") && !_apiServer.isValidApiName(rule)) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Invalid api name: " + rule + " provided in rules param");
}
ruleDetails.put(ApiConstants.RULE, new Rule(rule));
String permission = detail.get(ApiConstants.PERMISSION);

View File

@ -173,6 +173,7 @@ public class PrimaryDataStoreHelper {
public DataStore attachZone(DataStore store) {
StoragePoolVO pool = this.dataStoreDao.findById(store.getId());
storageMgr.createCapacityEntry(pool.getId());
pool.setScope(ScopeType.ZONE);
pool.setStatus(StoragePoolStatus.Up);
this.dataStoreDao.update(pool.getId(), pool);
@ -181,6 +182,7 @@ public class PrimaryDataStoreHelper {
public DataStore attachZone(DataStore store, HypervisorType hypervisor) {
StoragePoolVO pool = this.dataStoreDao.findById(store.getId());
storageMgr.createCapacityEntry(pool.getId());
pool.setScope(ScopeType.ZONE);
pool.setHypervisor(hypervisor);
pool.setStatus(StoragePoolStatus.Up);

View File

@ -2072,7 +2072,13 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
// Setup ROOT/DATA disk devices
//
for (DiskTO vol : sortedDisks) {
if (vol.getType() == Volume.Type.ISO || deployAsIs && vol.getType() == Volume.Type.ROOT) {
if (vol.getType() == Volume.Type.ISO) {
continue;
}
if (deployAsIs && vol.getType() == Volume.Type.ROOT) {
rootDiskTO = vol;
resizeRootDiskOnVMStart(vmMo, rootDiskTO, hyperHost, context);
continue;
}

View File

@ -31,6 +31,7 @@ import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.command.user.firewall.CreateFirewallRuleCmd;
import org.apache.cloudstack.api.command.user.vm.StartVMCmd;
import org.apache.cloudstack.api.command.user.volume.ResizeVolumeCmd;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.collections.CollectionUtils;
import org.apache.log4j.Level;
@ -70,6 +71,10 @@ import com.cloud.network.rules.RulesService;
import com.cloud.network.rules.dao.PortForwardingRulesDao;
import com.cloud.offering.ServiceOffering;
import com.cloud.resource.ResourceManager;
import com.cloud.storage.Volume;
import com.cloud.storage.VolumeApiService;
import com.cloud.storage.VolumeVO;
import com.cloud.storage.dao.VolumeDao;
import com.cloud.user.Account;
import com.cloud.user.SSHKeyPairVO;
import com.cloud.uservm.UserVm;
@ -118,6 +123,10 @@ public class KubernetesClusterResourceModifierActionWorker extends KubernetesClu
protected VMInstanceDao vmInstanceDao;
@Inject
protected UserVmManager userVmManager;
@Inject
protected VolumeApiService volumeService;
@Inject
protected VolumeDao volumeDao;
protected String kubernetesClusterNodeNamePrefix;
@ -268,6 +277,29 @@ public class KubernetesClusterResourceModifierActionWorker extends KubernetesClu
return plan(kubernetesCluster.getTotalNodeCount(), zone, offering);
}
protected void resizeNodeVolume(final UserVm vm) throws ManagementServerException {
try {
if (vm.getHypervisorType() == Hypervisor.HypervisorType.VMware && templateDao.findById(vm.getTemplateId()).isDeployAsIs()) {
List<VolumeVO> vmVols = volumeDao.findByInstance(vm.getId());
for (VolumeVO volumeVO : vmVols) {
if (volumeVO.getVolumeType() == Volume.Type.ROOT) {
ResizeVolumeCmd resizeVolumeCmd = new ResizeVolumeCmd();
resizeVolumeCmd = ComponentContext.inject(resizeVolumeCmd);
Field f = resizeVolumeCmd.getClass().getDeclaredField("size");
Field f1 = resizeVolumeCmd.getClass().getDeclaredField("id");
f.setAccessible(true);
f1.setAccessible(true);
f1.set(resizeVolumeCmd, volumeVO.getId());
f.set(resizeVolumeCmd, kubernetesCluster.getNodeRootDiskSize());
volumeService.resizeVolume(resizeVolumeCmd);
}
}
}
} catch (IllegalAccessException | NoSuchFieldException e) {
throw new ManagementServerException(String.format("Failed to resize volume of VM in the Kubernetes cluster : %s", kubernetesCluster.getName()), e);
}
}
protected void startKubernetesVM(final UserVm vm) throws ManagementServerException {
try {
StartVMCmd startVm = new StartVMCmd();
@ -275,6 +307,7 @@ public class KubernetesClusterResourceModifierActionWorker extends KubernetesClu
Field f = startVm.getClass().getDeclaredField("id");
f.setAccessible(true);
f.set(startVm, vm.getId());
resizeNodeVolume(vm);
userVmService.startVirtualMachine(startVm);
if (LOGGER.isInfoEnabled()) {
LOGGER.info(String.format("Started VM : %s in the Kubernetes cluster : %s", vm.getDisplayName(), kubernetesCluster.getName()));
@ -296,6 +329,7 @@ public class KubernetesClusterResourceModifierActionWorker extends KubernetesClu
for (int i = offset + 1; i <= nodeCount; i++) {
UserVm vm = createKubernetesNode(publicIpAddress, i);
addKubernetesClusterVm(kubernetesCluster.getId(), vm.getId());
resizeNodeVolume(vm);
startKubernetesVM(vm);
vm = userVmDao.findById(vm.getId());
if (vm == null) {

View File

@ -277,6 +277,7 @@ public class KubernetesClusterStartWorker extends KubernetesClusterResourceModif
UserVm k8sMasterVM = null;
k8sMasterVM = createKubernetesMaster(network, publicIpAddress);
addKubernetesClusterVm(kubernetesCluster.getId(), k8sMasterVM.getId());
resizeNodeVolume(k8sMasterVM);
startKubernetesVM(k8sMasterVM);
k8sMasterVM = userVmDao.findById(k8sMasterVM.getId());
if (k8sMasterVM == null) {
@ -296,6 +297,7 @@ public class KubernetesClusterStartWorker extends KubernetesClusterResourceModif
UserVm vm = null;
vm = createKubernetesAdditionalMaster(publicIpAddress, i);
addKubernetesClusterVm(kubernetesCluster.getId(), vm.getId());
resizeNodeVolume(vm);
startKubernetesVM(vm);
vm = userVmDao.findById(vm.getId());
if (vm == null) {

View File

@ -1208,17 +1208,6 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
}
}
@Override
public boolean isValidApiName(String apiName) {
if (apiName == null || apiName.isEmpty())
return false;
if (!s_apiNameCmdClassMap.containsKey(apiName))
return false;
return true;
}
// FIXME: rather than isError, we might was to pass in the status code to give more flexibility
private void writeResponse(final HttpResponse resp, final String responseText, final int statusCode, final String responseType, final String reasonPhrase) {
try {

View File

@ -962,8 +962,15 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
}
// if we are to use the existing disk offering
ImageFormat format = null;
if (newDiskOffering == null) {
if (volume.getVolumeType().equals(Volume.Type.ROOT) && diskOffering.getDiskSize() > 0) {
Long templateId = volume.getTemplateId();
if (templateId != null) {
VMTemplateVO template = _templateDao.findById(templateId);
format = template.getFormat();
}
if (volume.getVolumeType().equals(Volume.Type.ROOT) && diskOffering.getDiskSize() > 0 && format != null && format != ImageFormat.ISO) {
throw new InvalidParameterValueException(
"Failed to resize Root volume. The service offering of this Volume has been configured with a root disk size; "
+ "on such case a Root Volume can only be resized when changing to another Service Offering with a Root disk size. "

View File

@ -145,6 +145,8 @@ import com.cloud.agent.api.to.deployasis.OVFPropertyTO;
import com.cloud.agent.manager.Commands;
import com.cloud.alert.AlertManager;
import com.cloud.api.ApiDBUtils;
import com.cloud.api.query.dao.ServiceOfferingJoinDao;
import com.cloud.api.query.vo.ServiceOfferingJoinVO;
import com.cloud.capacity.Capacity;
import com.cloud.capacity.CapacityManager;
import com.cloud.configuration.Config;
@ -512,7 +514,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
@Inject
private UserVmDeployAsIsDetailsDao userVmDeployAsIsDetailsDao;
@Inject
private StorageManager _storageManager;
private StorageManager storageManager;
@Inject
private ServiceOfferingJoinDao serviceOfferingJoinDao;
private ScheduledExecutorService _executor = null;
private ScheduledExecutorService _vmIpFetchExecutor = null;
@ -2051,7 +2055,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
if (poolType == StoragePoolType.PowerFlex) {
// Get volume stats from the pool directly instead of sending cmd to host
// Added support for ScaleIO/PowerFlex pool only
answer = _storageManager.getVolumeStats(storagePool, cmd);
answer = storageManager.getVolumeStats(storagePool, cmd);
} else {
if (timeout > 0) {
cmd.setWait(timeout/1000);
@ -5313,9 +5317,21 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
throw new InvalidParameterValueException("Unable to use template " + templateId);
}
// Bootmode and boottype are not supported on VMWare dpeloy-as-is templates (since 4.15)
if (template.isDeployAsIs() && (cmd.getBootMode() != null || cmd.getBootType() != null)) {
throw new InvalidParameterValueException("Boot type and boot mode are not supported on VMware, as we honour what is defined in the template.");
ServiceOfferingJoinVO svcOffering = serviceOfferingJoinDao.findById(serviceOfferingId);
if (template.isDeployAsIs()) {
if (svcOffering != null && svcOffering.getRootDiskSize() != null && svcOffering.getRootDiskSize() > 0) {
throw new InvalidParameterValueException("Failed to deploy Virtual Machine as a service offering with root disk size specified cannot be used with a deploy as-is template");
}
if (cmd.getDetails().get("rootdisksize") != null) {
throw new InvalidParameterValueException("Overriding root disk size isn't supported for VMs deployed from defploy as-is templates");
}
// Bootmode and boottype are not supported on VMWare dpeloy-as-is templates (since 4.15)
if ((cmd.getBootMode() != null || cmd.getBootType() != null)) {
throw new InvalidParameterValueException("Boot type and boot mode are not supported on VMware, as we honour what is defined in the template.");
}
}
Long diskOfferingId = cmd.getDiskOfferingId();
@ -6349,7 +6365,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
HypervisorType hypervisorType = _volsDao.getHypervisorType(volume.getId());
if (hypervisorType.equals(HypervisorType.VMware)) {
try {
boolean isStoragePoolStoragepolicyComplaince = _storageManager.isStoragePoolComplaintWithStoragePolicy(Arrays.asList(volume), pool);
boolean isStoragePoolStoragepolicyComplaince = storageManager.isStoragePoolComplaintWithStoragePolicy(Arrays.asList(volume), pool);
if (!isStoragePoolStoragepolicyComplaince) {
throw new CloudRuntimeException(String.format("Storage pool %s is not storage policy compliance with the volume %s", pool.getUuid(), volume.getUuid()));
}

View File

@ -2692,6 +2692,7 @@
"message.delete.vpn.customer.gateway": "Please confirm that you want to delete this VPN Customer Gateway",
"message.delete.vpn.gateway": "Please confirm that you want to delete this VPN Gateway",
"message.deleting.vm": "Deleting VM",
"message.deployasis": "Selected template is Deploy As-Is i.e., the VM is deployed by importing an OVA with vApps directly into vCenter. Root disk(s) resize is allowed only on stopped VMs for such templates.",
"message.desc.add.new.lb.sticky.rule": "Add new LB sticky rule",
"message.desc.advanced.zone": "For more sophisticated network topologies. This network model provides the most flexibility in defining guest networks and providing custom network offerings such as firewall, VPN, or load balancer support.",
"message.desc.basic.zone": "Provide a single network where each VM instance is assigned an IP directly from the network. Guest isolation can be provided through layer-3 means such as security groups (IP address source filtering).",

View File

@ -22,7 +22,8 @@
style="width: 25vw;float: right;margin-bottom: 10px; z-index: 8"
:placeholder="$t('label.search')"
v-model="filter"
@search="handleSearch" />
@search="handleSearch"
autoFocus />
<a-table
size="small"

View File

@ -34,6 +34,7 @@
v-decorator="[item.resourcetype, {
initialValue: item.max
}]"
:autoFocus="index === 0"
/>
</a-form-item>
<div class="card-footer">

View File

@ -239,4 +239,10 @@ a {
.custom-icon path {
color: @primary-color;
}
}
}
@media only screen and (max-width: 576px) {
.ant-pagination-options {
display: inline-block;
}
}

View File

@ -173,7 +173,7 @@
}]"
v-model="formModel[field.name]"
:placeholder="field.description"
:autoFocus="fieldIndex === 0"
:autoFocus="fieldIndex === firstIndex"
/>
</span>
<span v-else-if="currentAction.mapping && field.name in currentAction.mapping && currentAction.mapping[field.name].options">
@ -183,6 +183,7 @@
rules: [{ required: field.required, message: `${$t('message.error.select')}` }]
}]"
:placeholder="field.description"
:autoFocus="fieldIndex === firstIndex"
>
<a-select-option key="" >{{ }}</a-select-option>
<a-select-option v-for="(opt, optIndex) in currentAction.mapping[field.name].options" :key="optIndex">
@ -204,6 +205,7 @@
:filterOption="(input, option) => {
return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
}"
:autoFocus="fieldIndex === firstIndex"
>
<a-select-option key="">{{ }}</a-select-option>
<a-select-option v-for="(opt, optIndex) in field.opts" :key="optIndex">
@ -224,6 +226,7 @@
:filterOption="(input, option) => {
return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
}"
:autoFocus="fieldIndex === firstIndex"
>
<a-select-option key="">{{ }}</a-select-option>
<a-select-option v-for="opt in field.opts" :key="opt.id">
@ -239,6 +242,7 @@
rules: [{ required: field.required, message: `${$t('message.error.select')}` }]
}]"
:placeholder="field.description"
:autoFocus="fieldIndex === firstIndex"
>
<a-select-option v-for="(opt, optIndex) in field.opts" :key="optIndex">
{{ opt.name && opt.type ? opt.name + ' (' + opt.type + ')' : opt.name || opt.description }}
@ -247,7 +251,7 @@
</span>
<span v-else-if="field.type==='long'">
<a-input-number
:autoFocus="fieldIndex === 0"
:autoFocus="fieldIndex === firstIndex"
style="width: 100%;"
v-decorator="[field.name, {
rules: [{ required: field.required, message: `${$t('message.validate.number')}` }]
@ -270,6 +274,7 @@
}]"
:placeholder="field.description"
@blur="($event) => handleConfirmBlur($event, field.name)"
:autoFocus="fieldIndex === firstIndex"
/>
</span>
<span v-else-if="field.name==='certificate' || field.name==='privatekey' || field.name==='certchain'">
@ -279,11 +284,12 @@
rules: [{ required: field.required, message: `${$t('message.error.required.input')}` }]
}]"
:placeholder="field.description"
:autoFocus="fieldIndex === firstIndex"
/>
</span>
<span v-else>
<a-input
:autoFocus="fieldIndex === 0"
:autoFocus="fieldIndex === firstIndex"
v-decorator="[field.name, {
rules: [{ required: field.required, message: `${$t('message.error.required.input')}` }]
}]"
@ -394,7 +400,8 @@ export default {
searchParams: {},
actions: [],
formModel: {},
confirmDirty: false
confirmDirty: false,
firstIndex: 0
}
},
beforeCreate () {
@ -756,6 +763,7 @@ export default {
})
}
}
this.getFirstIndexFocus()
this.showAction = true
for (const param of this.currentAction.paramFields) {
@ -771,6 +779,16 @@ export default {
this.fillEditFormFieldValues()
}
},
getFirstIndexFocus () {
this.firstIndex = 0
for (let fieldIndex = 0; fieldIndex < this.currentAction.paramFields.length; fieldIndex++) {
const field = this.currentAction.paramFields[fieldIndex]
if (!(this.currentAction.mapping && field.name in this.currentAction.mapping && this.currentAction.mapping[field.name].value)) {
this.firstIndex = fieldIndex
break
}
}
},
listUuidOpts (param) {
if (this.currentAction.mapping && param.name in this.currentAction.mapping && !this.currentAction.mapping[param.name].api) {
return

View File

@ -29,7 +29,7 @@
<div class="form__item">
<p class="form__label">{{ $t('label.accounttype') }}</p>
<a-select v-model="selectedAccountType" defaultValue="account">
<a-select v-model="selectedAccountType" defaultValue="account" autoFocus>
<a-select-option :value="$t('label.account')">{{ $t('label.account') }}</a-select-option>
<a-select-option :value="$t('label.project')">{{ $t('label.project') }}</a-select-option>
</a-select>
@ -77,9 +77,14 @@
</a-select>
</div>
<a-button type="primary" class="submit-btn" @click="submitData">
{{ $t('label.submit') }}
</a-button>
<div class="submit-btn">
<a-button @click="closeAction">
{{ $t('label.cancel') }}
</a-button>
<a-button type="primary" @click="submitData">
{{ $t('label.submit') }}
</a-button>
</div>
</div>
@ -183,6 +188,9 @@ export default {
this.selectedAccount = null
this.fetchNetworks()
},
closeAction () {
this.$emit('close-action')
},
submitData () {
let variableKey = ''
let variableValue = ''
@ -255,6 +263,10 @@ export default {
.submit-btn {
margin-top: 10px;
align-self: flex-end;
button {
margin-left: 10px;
}
}
.required {

View File

@ -26,7 +26,8 @@
v-decorator="['id', {
initialValue: this.selectedIso,
rules: [{ required: true, message: `${this.$t('label.required')}`}]
}]" >
}]"
autoFocus>
<a-select-option v-for="iso in isos" :key="iso.id">
{{ iso.displaytext || iso.name }}
</a-select-option>

View File

@ -29,7 +29,8 @@
style="margin-bottom: 10px;"
:placeholder="$t('label.search')"
v-model="filter"
@search="handleSearch" />
@search="handleSearch"
autoFocus />
</div>
<div class="form__item">

View File

@ -33,7 +33,8 @@
v-decorator="['name', {
rules: [{ required: true, message: $t('message.error.kubecluster.name') }]
}]"
:placeholder="apiParams.name.description"/>
:placeholder="apiParams.name.description"
autoFocus />
</a-form-item>
<a-form-item>
<span slot="label">

View File

@ -28,7 +28,8 @@
v-decorator="['name', {
rules: [{ required: true, message: $t('message.error.name') }]
}]"
:placeholder="apiParams.name.description"/>
:placeholder="apiParams.name.description"
autoFocus />
</a-form-item>
<a-form-item :label="$t('label.publickey')">
<a-input

View File

@ -36,7 +36,8 @@
rules: [{ required: true, message: $t('message.error.select') }]
}]"
@change="onChangeVolume"
:placeholder="apiParams.volumeid.description">
:placeholder="apiParams.volumeid.description"
autoFocus>
<a-select-option
v-for="volume in listVolumes"
:key="volume.id">

View File

@ -41,6 +41,7 @@
:options="zoneSelectOptions"
@change="onSelectZoneId"
:loading="loading.zones"
autoFocus
></a-select>
</a-form-item>
<a-form-item
@ -105,7 +106,8 @@
@update-template-iso="updateFieldValue" />
<span>
{{ $t('label.override.rootdisk.size') }}
<a-switch @change="val => { this.showRootDiskSizeChanger = val }" style="margin-left: 10px;"/>
<a-switch :disabled="template.deployasis" @change="val => { this.showRootDiskSizeChanger = val }" style="margin-left: 10px;"/>
<div v-if="template.deployasis"> {{ this.$t('message.deployasis') }} </div>
</span>
<disk-size-selection
v-show="showRootDiskSizeChanger"
@ -183,6 +185,7 @@
</a-form-item>
<compute-offering-selection
:compute-items="options.serviceOfferings"
:selected-template="template"
:row-count="rowCount.serviceOfferings"
:zoneId="zoneId"
:value="serviceOffering ? serviceOffering.id : ''"
@ -477,6 +480,7 @@
v-if="vm.templateid && ['KVM', 'VMware'].includes(hypervisor) && !template.deployasis">
<a-form-item :label="$t('label.boottype')">
<a-select
:autoFocus="vm.templateid && ['KVM', 'VMware'].includes(hypervisor) && !template.deployasis"
v-decorator="['boottype']"
@change="fetchBootModes"
>
@ -543,6 +547,9 @@
:options="keyboardSelectOptions"
></a-select>
</a-form-item>
<a-form-item :label="$t('label.action.start.instance')">
<a-switch v-decorator="['startvm', { initialValue: true }]" :checked="this.startvm" @change="checked => { this.startvm = checked }" />
</a-form-item>
</div>
</template>
</a-step>
@ -663,6 +670,7 @@ export default {
podId: null,
clusterId: null,
zoneSelected: false,
startvm: true,
vm: {
name: null,
zoneid: null,
@ -1419,6 +1427,9 @@ export default {
if (values.hypervisor && values.hypervisor.length > 0) {
deployVmData.hypervisor = values.hypervisor
}
deployVmData.startvm = values.startvm
// step 3: select service offering
deployVmData.serviceofferingid = values.computeofferingid
if (this.serviceOffering && this.serviceOffering.iscustomized) {

View File

@ -44,7 +44,8 @@
v-decorator="['volumeids']"
:placeholder="$t('label.delete.volumes')"
mode="multiple"
:loading="loading">
:loading="loading"
:autoFocus="$store.getters.userInfo.roletype !== 'Admin' && !$store.getters.features.allowuserexpungerecovervm">
<a-select-option v-for="volume in volumes" :key="volume.id">
{{ volume.name }}
</a-select-option>

View File

@ -30,7 +30,8 @@
</a-tooltip>
</span>
<a-input
v-decorator="['name', { initialValue: resource.name || '' }]" />
v-decorator="['name', { initialValue: resource.name || '' }]"
autoFocus />
</a-form-item>
<a-form-item>
<span slot="label">

View File

@ -165,7 +165,7 @@
{{ $t('message.network.addvm.desc') }}
<div class="modal-form">
<p class="modal-form__label">{{ $t('label.network') }}:</p>
<a-select :defaultValue="addNetworkData.network" @change="e => addNetworkData.network = e">
<a-select :defaultValue="addNetworkData.network" @change="e => addNetworkData.network = e" autoFocus>
<a-select-option
v-for="network in addNetworkData.allNetworks"
:key="network.id"
@ -195,14 +195,16 @@
showSearch
v-if="editNicResource.type==='Shared'"
v-model="editIpAddressValue"
:loading="listIps.loading">
:loading="listIps.loading"
:autoFocus="editNicResource.type==='Shared'">
<a-select-option v-for="ip in listIps.opts" :key="ip.ipaddress">
{{ ip.ipaddress }}
</a-select-option>
</a-select>
<a-input
v-else
v-model="editIpAddressValue"></a-input>
v-model="editIpAddressValue"
:autoFocus="editNicResource.type!=='Shared'"></a-input>
</div>
</a-modal>
@ -218,7 +220,7 @@
{{ $t('message.network.secondaryip') }}
</p>
<a-divider />
<a-input :placeholder="$t('label.new.secondaryip.description')" v-model="newSecondaryIp"></a-input>
<a-input :placeholder="$t('label.new.secondaryip.description')" v-model="newSecondaryIp" autoFocus></a-input>
<div style="margin-top: 10px; display: flex; justify-content:flex-end;">
<a-button @click="submitSecondaryIP" type="primary" style="margin-right: 10px;">{{ $t('label.add.secondary.ip') }}</a-button>
<a-button @click="closeModals">{{ $t('label.close') }}</a-button>

View File

@ -21,7 +21,8 @@
:placeholder="$t('label.search')"
v-model="searchQuery"
style="margin-bottom: 10px;"
@search="fetchData" />
@search="fetchData"
autoFocus />
<a-table
size="small"
style="overflow-y: auto"

View File

@ -45,7 +45,8 @@
}
}]
}]"
:placeholder="apiParams.size.description"/>
:placeholder="apiParams.size.description"
autoFocus />
</a-form-item>
<a-form-item>
<span slot="label">

View File

@ -43,7 +43,8 @@
}"
:loading="podsLoading"
:placeholder="apiParams.podid.description"
@change="handlePodChange">
@change="handlePodChange"
:autoFocus="this.$store.getters.userInfo.roletype === 'Admin'">
<a-select-option v-for="pod in this.pods" :key="pod.id">
{{ pod.name }}
</a-select-option>

View File

@ -44,7 +44,8 @@
return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
}"
:loading="kubernetesVersionLoading"
:placeholder="apiParams.kubernetesversionid.description">
:placeholder="apiParams.kubernetesversionid.description"
autoFocus >
<a-select-option v-for="(opt, optIndex) in this.kubernetesVersions" :key="optIndex">
{{ opt.name || opt.description }}
</a-select-option>

View File

@ -61,7 +61,8 @@
rules: [{required: true, message: $t('message.error.required.input')}]
}]"
:min="1"
:max="59"/>
:max="59"
autoFocus />
</a-tooltip>
</a-form-item>
</a-col>

View File

@ -21,7 +21,8 @@
style="width: 25vw;float: right;margin-bottom: 10px; z-index: 8"
:placeholder="$t('label.search')"
v-model="filter"
@search="handleSearch" />
@search="handleSearch"
autoFocus />
<a-table
:columns="columns"
:dataSource="tableSource"
@ -63,6 +64,10 @@ export default {
type: Array,
default: () => []
},
selectedTemplate: {
type: Object,
default: () => {}
},
rowCount: {
type: Number,
default: () => 0
@ -161,6 +166,9 @@ export default {
(item.iscustomized === true && maxMemory < this.minimumMemory))) {
disabled = true
}
if (this.selectedTemplate && this.selectedTemplate.hypervisor === 'VMware' && this.selectedTemplate.deployasis && item.rootdisksize) {
disabled = true
}
return {
key: item.id,
name: item.name,
@ -238,6 +246,9 @@ export default {
return {
on: {
click: () => {
if (record.disabled) {
return
}
this.selectedRowKeys = [record.key]
this.$emit('select-compute-item', record.key)
}

View File

@ -35,6 +35,7 @@
</a-col>
<a-col :md="4" :lg="4">
<a-input-number
:autoFocus="isConstrained"
v-model="cpuNumberInputValue"
@change="($event) => updateComputeCpuNumber($event)"
/>
@ -48,6 +49,7 @@
:validate-status="errors.cpuspeed.status"
:help="errors.cpuspeed.message">
<a-input-number
:autoFocus="!isConstrained"
v-model="cpuSpeedInputValue"
@change="($event) => updateComputeCpuSpeed($event)"
/>

View File

@ -23,6 +23,7 @@
<a-col :md="4" :lg="4">
<span style="display: inline-flex">
<a-input-number
autoFocus
v-model="inputValue"
@change="($event) => updateDiskSize($event)"
/>

View File

@ -28,6 +28,7 @@
<span slot="offering" slot-scope="text, record">
<a-select
autoFocus
v-if="validOfferings[record.id] && validOfferings[record.id].length > 0"
@change="updateOffering($event, record.id)"
:defaultValue="validOfferings[record.id][0].id">

View File

@ -30,9 +30,10 @@
<div>{{ text }}</div>
<small v-if="record.type!=='L2'">{{ $t('label.cidr') + ': ' + record.cidr }}</small>
</template>
<template slot="ipAddress" slot-scope="text, record">
<a-form-item v-if="record.type!=='L2'">
<template slot="ipAddress" slot-scope="text, record, index">
<a-form-item v-if="record.type!=='L2' && index === 0">
<a-input
:autoFocus="record.type!=='L2'"
style="width: 150px;"
v-decorator="['ipAddress' + record.id, {
rules: [{
@ -49,9 +50,10 @@
</a-input>
</a-form-item>
</template>
<template slot="macAddress" slot-scope="text, record">
<template slot="macAddress" slot-scope="text, record, index">
<a-form-item>
<a-input
:autoFocus="record.type==='L2' && index === 0"
style="width: 150px;"
:placeholder="$t('label.macaddress')"
v-decorator="[`macAddress` + record.id, {

View File

@ -31,7 +31,8 @@
initialValue: selectedRole,
rules: [{ required: true, message: $t('message.error.select') }] }]"
:loading="roleLoading"
:placeholder="apiParams.roleid.description">
:placeholder="apiParams.roleid.description"
autoFocus>
<a-select-option v-for="role in roles" :key="role.id">
{{ role.name + ' (' + role.type + ')' }}
</a-select-option>

View File

@ -50,7 +50,7 @@
@submit="handleSubmit"
layout="vertical" >
<a-form-item :label="$t('label.filterby')">
<a-select @change="fetchListLdapUsers" v-model="selectedFilter" >
<a-select @change="fetchListLdapUsers" v-model="selectedFilter" autoFocus >
<a-select-option v-for="opt in filters" :key="opt.id" >
{{ opt.name }}
</a-select-option>

View File

@ -30,7 +30,8 @@
v-decorator="['username', {
rules: [{ required: true, message: $t('message.error.required.input') }]
}]"
:placeholder="apiParams.username.description" />
:placeholder="apiParams.username.description"
autoFocus/>
</a-form-item>
<a-row :gutter="12">
<a-col :md="24" :lg="12">

View File

@ -33,7 +33,8 @@
v-decorator="['currentpassword', {
rules: [{ required: true, message: $t('message.error.current.password') }]
}]"
:placeholder="$t('message.error.current.password')"/>
:placeholder="$t('message.error.current.password')"
autoFocus />
</a-form-item>
<a-form-item>
<span slot="label">

View File

@ -25,6 +25,7 @@
}]"
:checked="isSamlEnabled"
@change="val => { isSamlEnabled = val }"
autoFocus
/>
</a-form-item>
<a-form-item :label="$t('label.samlentity')">

View File

@ -33,7 +33,8 @@
v-decorator="['name', {
rules: [{ required: true, message: $t('message.error.required.input') }]
}]"
:placeholder="createRoleApiParams.name.description" />
:placeholder="createRoleApiParams.name.description"
autoFocus />
</a-form-item>
<a-form-item>

View File

@ -68,6 +68,7 @@
rules: [{ required: field.required, message: $t('message.error.select') }]
}]"
:placeholder="field.description"
:autoFocus="fieldIndex === firstIndex"
>
<a-select-option v-for="(opt, optIndex) in action.mapping[field.name].options" :key="optIndex">
{{ opt }}
@ -87,6 +88,7 @@
:filterOption="(input, option) => {
return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
}"
:autoFocus="fieldIndex === firstIndex"
>
<a-select-option v-for="(opt, optIndex) in field.opts" :key="optIndex">
{{ opt.name || opt.description || opt.traffictype || opt.publicip }}
@ -101,6 +103,7 @@
rules: [{ required: field.required, message: $t('message.error.select') }]
}]"
:placeholder="field.description"
:autoFocus="fieldIndex === firstIndex"
>
<a-select-option v-for="(opt, optIndex) in field.opts" :key="optIndex">
{{ opt.name && opt.type ? opt.name + ' (' + opt.type + ')' : opt.name || opt.description }}
@ -113,6 +116,7 @@
rules: [{ required: field.required, message: `${$t('message.validate.number')}` }]
}]"
:placeholder="field.description"
:autoFocus="fieldIndex === firstIndex"
/>
</span>
<span v-else>
@ -120,7 +124,8 @@
v-decorator="[field.name, {
rules: [{ required: field.required, message: $t('message.error.required.input') }]
}]"
:placeholder="field.description" />
:placeholder="field.description"
:autoFocus="fieldIndex === firstIndex" />
</span>
</a-form-item>
</a-form>
@ -151,6 +156,16 @@ export default {
beforeCreate () {
this.form = this.$form.createForm(this)
},
created () {
this.firstIndex = 0
for (let fieldIndex = 0; fieldIndex < this.action.paramFields.length; fieldIndex++) {
const field = this.action.paramFields[fieldIndex]
if (!(this.action.mapping && field.name in this.action.mapping && this.action.mapping[field.name].value)) {
this.firstIndex = fieldIndex
break
}
}
},
mounted () {
if (this.action.dataView && this.action.icon === 'edit') {
this.fillEditFormFieldValues()

View File

@ -30,7 +30,8 @@
v-decorator="['username', {
rules: [{ required: true, message: $t('message.error.required.input') }]
}]"
:placeholder="apiParams.username.description" />
:placeholder="apiParams.username.description"
autoFocus />
</a-form-item>
<a-form-item>
<span slot="label">

View File

@ -62,7 +62,8 @@
v-decorator="['name', {
rules: [{ required: true, message: $t('message.error.required.input') }]
}]"
:placeholder="importRoleApiParams.name.description" />
:placeholder="importRoleApiParams.name.description"
autoFocus />
</a-form-item>
<a-form-item>

View File

@ -18,7 +18,8 @@
<template>
<a-select
:value="defaultValue"
@change="handleChange">
@change="handleChange"
autoFocus>
<a-select-option value="allow">{{ $t('label.allow') }}</a-select-option>
<a-select-option value="deny">{{ $t('label.deny') }}</a-select-option>
</a-select>

View File

@ -33,7 +33,8 @@
v-decorator="['semanticversion', {
rules: [{ required: true, message: $t('message.error.kuberversion') }]
}]"
:placeholder="apiParams.semanticversion.description"/>
:placeholder="apiParams.semanticversion.description"
autoFocus />
</a-form-item>
<a-form-item>
<span slot="label">

View File

@ -108,7 +108,8 @@
:filterOption="(input, option) => {
return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
}"
:loading="zoneLoading">
:loading="zoneLoading"
autoFocus>
<a-select-option v-for="zone in zones" :key="zone.id">
{{ zone.name }}
</a-select-option>

View File

@ -29,7 +29,7 @@
layout="vertical">
<a-form-item v-if="currentForm === 'Create'" :label="$t('label.url')">
<a-input
autoFocus
:autoFocus="currentForm === 'Create'"
v-decorator="['url', {
rules: [{ required: true, message: `${this.$t('label.upload.iso.from.local')}` }]
}]"
@ -57,7 +57,8 @@
v-decorator="['name', {
rules: [{ required: true, message: `${this.$t('message.error.required.input')}` }]
}]"
:placeholder="apiParams.name.description" />
:placeholder="apiParams.name.description"
:autoFocus="currentForm !== 'Create'" />
</a-form-item>
<a-form-item :label="$t('label.displaytext')">

View File

@ -31,7 +31,7 @@
<a-row :gutter="12">
<a-form-item :label="$t('label.url')">
<a-input
autoFocus
:autoFocus="currentForm === 'Create'"
v-decorator="['url', {
rules: [{ required: true, message: `${this.$t('message.error.required.input')}` }]
}]"
@ -64,7 +64,8 @@
v-decorator="['name', {
rules: [{ required: true, message: `${this.$t('message.error.required.input')}` }]
}]"
:placeholder="apiParams.name.description" />
:placeholder="apiParams.name.description"
:autoFocus="currentForm !== 'Create'"/>
</a-form-item>
</a-row>
<a-row :gutter="12">

View File

@ -100,7 +100,8 @@
:filterOption="(input, option) => {
return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
}"
:loading="zoneLoading">
:loading="zoneLoading"
autoFocus>
<a-select-option v-for="zone in zones" :key="zone.id">
{{ zone.name }}
</a-select-option>

View File

@ -34,7 +34,8 @@
return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
}"
:loading="stateLoading"
:placeholder="apiParams.state.description">
:placeholder="apiParams.state.description"
autoFocus >
<a-select-option v-for="(opt, optIndex) in this.states" :key="optIndex">
{{ opt.name || opt.description }}
</a-select-option>

View File

@ -23,7 +23,11 @@
<div class="form__item">
<p class="form__label">{{ $t('label.operation') }}</p>
<a-select v-model="selectedOperation" :defaultValue="$t('label.add')" @change="fetchData">
<a-select
v-model="selectedOperation"
:defaultValue="$t('label.add')"
@change="fetchData"
autoFocus>
<a-select-option :value="$t('label.add')">{{ $t('label.add') }}</a-select-option>
<a-select-option :value="$t('label.remove')">{{ $t('label.remove') }}</a-select-option>
<a-select-option :value="$t('label.reset')">{{ $t('label.reset') }}</a-select-option>

View File

@ -26,7 +26,10 @@
<a-icon type="info-circle" style="color: rgba(0,0,0,.45)" />
</a-tooltip>
</span>
<a-select v-decorator="['scope', { initialValue: 'cluster' }]" @change="val => { this.scope = val }">
<a-select
v-decorator="['scope', { initialValue: 'cluster' }]"
@change="val => { this.scope = val }"
autoFocus>
<a-select-option :value="'cluster'"> {{ $t('label.clusterid') }} </a-select-option>
<a-select-option :value="'zone'"> {{ $t('label.zoneid') }} </a-select-option>
</a-select>

View File

@ -20,7 +20,7 @@
<a-spin :spinning="loading">
<a-form :form="form" layout="vertical">
<a-form-item :label="$t('label.name')">
<a-input v-decorator="['name']" />
<a-input v-decorator="['name']" autoFocus />
</a-form-item>
<a-form-item :label="$t('label.providername')">
<a-select

View File

@ -20,7 +20,7 @@
<div class="form">
<div class="form__item">
<div class="form__label"><span class="required">* </span>{{ $t('label.zonenamelabel') }}</div>
<a-select v-model="zoneId" @change="fetchPods">
<a-select v-model="zoneId" @change="fetchPods" autoFocus>
<a-select-option
v-for="zone in zonesList"
:value="zone.id"

View File

@ -21,7 +21,7 @@
<div class="form__item">
<div class="form__label"><span class="required">* </span>{{ $t('label.zonenamelabel') }}</div>
<a-select v-model="zoneId" @change="fetchPods">
<a-select v-model="zoneId" @change="fetchPods" autoFocus>
<a-select-option
v-for="zone in zonesList"
:value="zone.id"

View File

@ -32,6 +32,7 @@
}]"
:loading="loading"
@change="val => { selectedStore = val }"
autoFocus
>
<a-select-option
v-for="store in imageStores"

View File

@ -24,7 +24,8 @@
v-decorator="['zoneid', {
initialValue: this.zoneId,
rules: [{ required: true, message: `${$t('label.required')}` }] }
]">
]"
autoFocus>
<a-select-option
v-for="zone in zonesList"
:value="zone.id"

View File

@ -74,6 +74,7 @@
v-decorator="['range', {
rules: [{ required: true, message: `${$t('label.required')}` }]
}]"
autoFocus
></a-input>
</a-form-item>

View File

@ -27,6 +27,7 @@
</a-tooltip>
</span>
<a-select
autoFocus
v-decorator="['id', {
initialValue: selectedType,
rules: [{ required: true, message: $t('message.error.select') }] }]"

View File

@ -81,6 +81,7 @@
>
<a-form-item :label="$t('label.podid')" class="form__item">
<a-select
autoFocus
v-decorator="['pod', {
rules: [{ required: true, message: `${$t('label.required')}` }]
}]"

View File

@ -117,7 +117,7 @@
<a-spin :spinning="domainsLoading">
<div style="margin-bottom: 10px;">
<div class="list__label">{{ $t('label.account') }}:</div>
<a-input v-model="addAccount.account"></a-input>
<a-input v-model="addAccount.account" autoFocus></a-input>
</div>
<div>
<div class="list__label">{{ $t('label.domain') }}:</div>
@ -145,6 +145,7 @@
>
<a-form-item :label="$t('label.gateway')" class="form__item">
<a-input
autoFocus
v-decorator="['gateway', { rules: [{ required: true, message: `${$t('label.required')}` }] }]">
</a-input>
</a-form-item>

View File

@ -79,6 +79,7 @@
>
<a-form-item :label="$t('label.podid')" class="form__item">
<a-select
autoFocus
v-decorator="['pod', {
rules: [{ required: true, message: `${$t('label.required')}` }]
}]"

View File

@ -80,6 +80,7 @@
:label="$t('label.' + field.name)">
<span v-if="field.name==='password'">
<a-input-password
:autoFocus="index===0"
v-decorator="[field.name, {
rules: [
{
@ -92,6 +93,7 @@
</span>
<span v-else-if="field.type==='boolean'">
<a-switch
:autoFocus="index===0"
v-decorator="[field.name, {
rules: [{
required: field.required,
@ -103,6 +105,7 @@
</span>
<span v-else-if="field.type==='uuid'">
<a-select
:autoFocus="index===0"
v-decorator="[field.name, {
rules: [{
required: field.required,
@ -118,6 +121,7 @@
</span>
<span v-else>
<a-input
:autoFocus="index===0"
v-decorator="[field.name, {
rules: [
{

View File

@ -25,6 +25,7 @@
<a-col :md="24" :lg="24">
<a-form-item :label="$t('label.ip')">
<a-input
autoFocus
v-decorator="['ip', {
rules: [{ required: true, message: $t('message.error.required.input') }]
}]" />

View File

@ -25,6 +25,7 @@
<a-col :md="24" :lg="24">
<a-form-item :label="$t('label.ip')">
<a-input
autoFocus
v-decorator="['ip', {
rules: [{ required: true, message: $t('message.error.required.input') }]
}]" />

View File

@ -25,6 +25,7 @@
<a-col :md="24" :lg="24">
<a-form-item :label="$t('label.ip')">
<a-input
autoFocus
v-decorator="['ip', {
rules: [{ required: true, message: $t('message.error.required.input') }]
}]" />

View File

@ -25,6 +25,7 @@
<a-col :md="24" :lg="24">
<a-form-item :label="$t('label.ip')">
<a-input
autoFocus
v-decorator="['ip', {
rules: [{ required: true, message: $t('message.error.required.input') }]
}]" />

View File

@ -25,6 +25,7 @@
<a-col :md="24" :lg="24">
<a-form-item :label="$t('label.ip')">
<a-input
autoFocus
v-decorator="['ip', {
rules: [{ required: true, message: $t('message.error.required.input') }]
}]" />

View File

@ -63,7 +63,8 @@
</span>
<a-switch
v-decorator="[$t('performfreshchecks')]"
:placeholder="apiParams.performfreshchecks.description" />
:placeholder="apiParams.performfreshchecks.description"
autoFocus/>
</a-form-item>
</a-form>
</a-spin>

View File

@ -46,6 +46,7 @@
}]
}]"
style="width: 100%;"
autoFocus
/>
</a-form-item>
<span :style="{ display: 'inline-block', width: '24px', textAlign: 'center' }">

View File

@ -42,6 +42,7 @@
rules: [{ required: true, message: $t('message.error.gateway') }]
}]"
:placeholder="$t('label.gateway')"
autoFocus
/>
</a-form-item>
<a-form-item :style="{ display: 'inline-block', width: '14%' }">

View File

@ -45,6 +45,7 @@
]
}]"
:allowClear="true"
:autoFocus="index === 0"
>
<a-select-option
v-for="option in field.options"
@ -58,6 +59,7 @@
v-else-if="field.switch"
v-decorator="[field.key]"
:default-checked="isChecked(field)"
:autoFocus="index === 0"
/>
<a-input
v-else-if="field.password"
@ -71,6 +73,7 @@
}
]
}]"
:autoFocus="index === 0"
/>
<a-input
v-else
@ -89,6 +92,7 @@
}
]
}]"
:autoFocus="index === 0"
/>
</a-form-item>
</a-form>

View File

@ -29,7 +29,7 @@
:pagination="false"
style="margin-bottom: 24px;">
<template slot="name" slot-scope="text, record">
<a-input :value="text" @change="e => onCellChange(record.key, 'name', e.target.value)" />
<a-input :value="text" @change="e => onCellChange(record.key, 'name', e.target.value)" autoFocus />
</template>
<template slot="isolationMethod" slot-scope="text, record">
<a-select

View File

@ -35,6 +35,7 @@
initialValue: name
}]
}]"
autoFocus
/>
</a-form-item>
<a-form-item

View File

@ -50,6 +50,7 @@
v-decorator="['securityGroupsEnabled', { valuePropName: 'checked' }]"
:value="securityGroupsEnabled"
:disabled="!isAdvancedZone"
autoFocus
/>
</a-form-item>
<span>{{ $t('label.menu.security.groups') }}</span>

View File

@ -104,7 +104,9 @@
<div class="add-tags__input">
<p class="add-tags__label">{{ $t('label.key') }}</p>
<a-form-item>
<a-input v-decorator="['key', { rules: [{ required: true, message: $t('message.specifiy.tag.key')}] }]" />
<a-input
autoFocus
v-decorator="['key', { rules: [{ required: true, message: $t('message.specifiy.tag.key')}] }]" />
</a-form-item>
</div>
<div class="add-tags__input">
@ -133,7 +135,7 @@
<a-modal :title="ruleModalTitle" :maskClosable="false" v-model="ruleModalVisible" @ok="handleRuleModalForm">
<a-form :form="ruleForm" @submit="handleRuleModalForm">
<a-form-item :label="$t('label.number')">
<a-input-number style="width: 100%" v-decorator="['number']" />
<a-input-number autoFocus style="width: 100%" v-decorator="['number']" />
</a-form-item>
<a-form-item :label="$t('label.cidrlist')">
<a-input v-decorator="['cidrlist']" />

View File

@ -34,7 +34,8 @@
v-decorator="['name', {
rules: [{ required: true, message: $t('message.error.name') }]
}]"
:placeholder="this.$t('label.name')"/>
:placeholder="this.$t('label.name')"
autoFocus/>
</a-form-item>
<a-form-item>
<span slot="label">

View File

@ -34,7 +34,8 @@
v-decorator="['name', {
rules: [{ required: true, message: $t('message.error.name') }]
}]"
:placeholder="this.$t('label.name')"/>
:placeholder="this.$t('label.name')"
autoFocus/>
</a-form-item>
<a-form-item>
<span slot="label">

View File

@ -34,7 +34,8 @@
v-decorator="['name', {
rules: [{ required: true, message: $t('message.error.name') }]
}]"
:placeholder="this.$t('label.name')"/>
:placeholder="this.$t('label.name')"
autoFocus />
</a-form-item>
<a-form-item>
<span slot="label">

View File

@ -31,6 +31,7 @@
</a-tooltip>
</span>
<a-input
autoFocus
v-decorator="['gateway', {
rules: [{ required: true, message: $t('message.error.gateway') }]
}]"

View File

@ -31,7 +31,8 @@
v-decorator="['name', {
rules: [{ required: true, message: $t('message.error.required.input') }]
}]"
:placeholder="apiParams.name.description"/>
:placeholder="apiParams.name.description"
autoFocus/>
</a-form-item>
<a-form-item>
<span slot="label">

View File

@ -31,7 +31,8 @@
rules: [{ required: true, message: `${$t('label.required')}` }],
}
]"
:placeholder="$t('label.vpncustomergatewayname')" />
:placeholder="$t('label.vpncustomergatewayname')"
autoFocus />
</a-form-item>
<a-form-item>
<span slot="label">

View File

@ -21,7 +21,7 @@
<div class="form">
<div class="form__item">
<div class="form__label">{{ $t('label.sourcecidr') }}</div>
<a-input v-model="newRule.cidrlist"></a-input>
<a-input v-model="newRule.cidrlist" autoFocus></a-input>
</div>
<div class="form__item">
<div class="form__label">{{ $t('label.destcidr') }}</div>

View File

@ -19,7 +19,11 @@
<div class="list" :loading="loading">
<div class="list__header">
<div class="list__header__col" v-if="tiersSelect">
<a-select @change="handleTierSelect" v-model="vpcTiers" :placeholder="$t('label.select.tier')">
<a-select
autoFocus
@change="handleTierSelect"
v-model="vpcTiers"
:placeholder="$t('label.select.tier')">
<a-select-option v-for="network in networksList" :key="network.id" :value="network.id">
{{ network.name }}
</a-select-option>

View File

@ -21,7 +21,7 @@
<div class="form">
<div class="form__item">
<div class="form__label">{{ $t('label.sourcecidr') }}</div>
<a-input v-model="newRule.cidrlist"></a-input>
<a-input autoFocus v-model="newRule.cidrlist"></a-input>
</div>
<div class="form__item">
<div class="form__label">{{ $t('label.protocol') }}</div>
@ -110,7 +110,7 @@
<div class="add-tags">
<div class="add-tags__input">
<p class="add-tags__label">{{ $t('label.key') }}</p>
<a-input v-model="newTag.key"></a-input>
<a-input autoFocus v-model="newTag.key"></a-input>
</div>
<div class="add-tags__input">
<p class="add-tags__label">{{ $t('label.value') }}</p>

View File

@ -30,7 +30,11 @@
<div class="form">
<div class="form__item">
<div class="form__label">{{ $t('label.protocol') }}</div>
<a-select v-model="newRule.protocol" style="width: 100%;" @change="resetRulePorts">
<a-select
autoFocus
v-model="newRule.protocol"
style="width: 100%;"
@change="resetRulePorts">
<a-select-option value="tcp">{{ $t('label.tcp') | capitalise }}</a-select-option>
<a-select-option value="udp">{{ $t('label.udp') | capitalise }}</a-select-option>
<a-select-option value="icmp">{{ $t('label.icmp') | capitalise }}</a-select-option>
@ -127,7 +131,9 @@
<div class="add-tags__input">
<p class="add-tags__label">{{ $t('label.key') }}</p>
<a-form-item>
<a-input v-decorator="['key', { rules: [{ required: true, message: this.$t('message.specifiy.tag.key')}] }]" />
<a-input
autoFocus
v-decorator="['key', { rules: [{ required: true, message: this.$t('message.specifiy.tag.key')}] }]" />
</a-form-item>
</div>
<div class="add-tags__input">

View File

@ -37,6 +37,7 @@
</span>
<a-icon v-if="addVmModalNicLoading" type="loading"></a-icon>
<a-select
:autoFocus="!addVmModalNicLoading && iLb.virtualmachineid[index] === vm.id && index === 0"
v-else-if="!addVmModalNicLoading && iLb.virtualmachineid[index] === vm.id"
mode="multiple"
v-model="iLb.vmguestip[index]"
@ -52,7 +53,10 @@
<span></span>
<span>{{ vm.account }}</span>
<span>{{ vm.zonename }}</span>
<a-checkbox :value="vm.id" @change="e => fetchNics(e, index)" />
<a-checkbox
:autoFocus="!(!addVmModalNicLoading && iLb.virtualmachineid[index] === vm.id) && index === 0"
:value="vm.id"
@change="e => fetchNics(e, index)" />
</div>
<a-divider/>
<a-pagination

View File

@ -29,6 +29,7 @@
<div v-if="$route.path.startsWith('/vpc')">
Select Tier:
<a-select
autoFocus
style="width: 40%; margin-left: 15px;margin-bottom: 15px"
:loading="fetchLoading"
defaultActiveFirstOption
@ -110,6 +111,7 @@
<a-alert :message="$t('message.action.acquire.ip')" type="warning" />
<a-form-item :label="$t('label.ipaddress')">
<a-select
autoFocus
style="width: 100%;"
showSearch
v-model="acquireIp">

View File

@ -21,7 +21,7 @@
<div class="form">
<div class="form__item" ref="newRuleName">
<div class="form__label"><span class="form__required">*</span>{{ $t('label.name') }}</div>
<a-input v-model="newRule.name"></a-input>
<a-input autoFocus v-model="newRule.name"></a-input>
<span class="error-text">{{ $t('label.required') }}</span>
</div>
<div class="form__item" ref="newRulePublicPort">
@ -154,7 +154,9 @@
<div class="add-tags__input">
<p class="add-tags__label">{{ $t('label.key') }}</p>
<a-form-item>
<a-input v-decorator="['key', { rules: [{ required: true, message: this.$t('message.specifiy.tag.key')}] }]" />
<a-input
autoFocus
v-decorator="['key', { rules: [{ required: true, message: this.$t('message.specifiy.tag.key')}] }]" />
</a-form-item>
</div>
<div class="add-tags__input">
@ -193,7 +195,7 @@
<a-form :form="stickinessPolicyForm" @submit="handleSubmitStickinessForm" class="custom-ant-form">
<a-form-item :label="$t('label.stickiness.method')">
<a-select v-decorator="['methodname']" @change="handleStickinessMethodSelectChange">
<a-select autoFocus v-decorator="['methodname']" @change="handleStickinessMethodSelectChange">
<a-select-option value="LbCookie">{{ $t('label.lb.cookie') }}</a-select-option>
<a-select-option value="AppCookie">{{ $t('label.app.cookie') }}</a-select-option>
<a-select-option value="SourceBased">{{ $t('label.source.based') }}</a-select-option>
@ -265,7 +267,7 @@
<div class="edit-rule" v-if="selectedRule">
<div class="edit-rule__item">
<p class="edit-rule__label">{{ $t('label.name') }}</p>
<a-input v-model="editRuleDetails.name" />
<a-input autoFocus v-model="editRuleDetails.name" />
</div>
<div class="edit-rule__item">
<p class="edit-rule__label">{{ $t('label.algorithm') }}</p>
@ -304,6 +306,7 @@
v-if="'vpcid' in resource && !('associatednetworkid' in resource)">
<strong>{{ $t('label.select.tier') }} </strong>
<a-select
:autoFocus="'vpcid' in resource && !('associatednetworkid' in resource)"
v-model="selectedTier"
@change="fetchVirtualMachines()"
:placeholder="$t('label.select.tier')" >
@ -316,6 +319,7 @@
</a-select>
</span>
<a-input-search
:autoFocus="!('vpcid' in resource && !('associatednetworkid' in resource))"
class="input-search"
:placeholder="$t('label.search')"
v-model="searchQuery"

View File

@ -23,6 +23,7 @@
<div class="form__label">{{ $t('label.privateport') }}</div>
<a-input-group class="form__item__input-container" compact>
<a-input
autoFocus
v-model="newRule.privateport"
:placeholder="$t('label.start')"
style="border-right: 0; width: 60px; margin-right: 0;"></a-input>
@ -136,7 +137,7 @@
<div class="add-tags">
<div class="add-tags__input">
<p class="add-tags__label">{{ $t('label.key') }}</p>
<a-input v-model="newTag.key"></a-input>
<a-input autoFocus v-model="newTag.key"></a-input>
</div>
<div class="add-tags__input">
<p class="add-tags__label">{{ $t('label.value') }}</p>
@ -176,6 +177,7 @@
v-if="'vpcid' in resource && !('associatednetworkid' in resource)">
<strong>{{ $t('label.select.tier') }} </strong>
<a-select
:autoFocu="'vpcid' in resource && !('associatednetworkid' in resource)"
v-model="selectedTier"
@change="fetchVirtualMachines()"
:placeholder="$t('label.select.tier')" >
@ -188,6 +190,7 @@
</a-select>
</span>
<a-input-search
:autoFocu="!('vpcid' in resource && !('associatednetworkid' in resource))"
class="input-search"
:placeholder="$t('label.search')"
v-model="searchQuery"

View File

@ -18,7 +18,7 @@
<template>
<a-spin :spinning="componentLoading">
<div class="new-route">
<a-input v-model="newRoute" icon="plus" :placeholder="$t('label.cidr.destination.network')"></a-input>
<a-input v-model="newRoute" icon="plus" :placeholder="$t('label.cidr.destination.network')" autoFocus></a-input>
<a-button type="primary" :disabled="!('createStaticRoute' in $store.getters.apis)" @click="handleAdd">{{ $t('label.add.route') }}</a-button>
</div>
@ -43,7 +43,9 @@
<div class="add-tags__input">
<p class="add-tags__label">{{ $t('label.key') }}</p>
<a-form-item>
<a-input v-decorator="['key', { rules: [{ required: true, message: this.$t('message.specifiy.tag.key')}] }]" />
<a-input
autoFocus
v-decorator="['key', { rules: [{ required: true, message: this.$t('message.specifiy.tag.key')}] }]" />
</a-form-item>
</div>
<div class="add-tags__input">

View File

@ -76,7 +76,9 @@
@ok="handleNetworkAclFormSubmit">
<a-form @submit.prevent="handleNetworkAclFormSubmit" :form="networkAclForm">
<a-form-item :label="$t('label.add.list.name')">
<a-input v-decorator="['name', {rules: [{ required: true, message: `${$t('label.required')}` }]}]"></a-input>
<a-input
v-decorator="['name', {rules: [{ required: true, message: `${$t('label.required')}` }]}]"
autoFocus></a-input>
</a-form-item>
<a-form-item :label="$t('label.description')">
<a-input v-decorator="['description', {rules: [{ required: true, message: `${$t('label.required')}` }]}]"></a-input>
@ -131,7 +133,7 @@
<p>{{ $t('message.add.new.gateway.to.vpc') }}</p>
<a-form @submit.prevent="handleGatewayFormSubmit" :form="gatewayForm">
<a-form-item :label="$t('label.physicalnetworkid')">
<a-select v-decorator="['physicalnetwork']">
<a-select v-decorator="['physicalnetwork']" autoFocus>
<a-select-option v-for="item in physicalnetworks" :key="item.id" :value="item.id">
{{ item.name }}
</a-select-option>
@ -255,7 +257,7 @@
<a-spin :spinning="modals.vpnConnectionLoading">
<a-form @submit.prevent="handleVpnConnectionFormSubmit" :form="vpnConnectionForm">
<a-form-item :label="$t('label.vpncustomergatewayid')">
<a-select v-decorator="['vpncustomergateway']">
<a-select v-decorator="['vpncustomergateway']" autoFocus>
<a-select-option v-for="item in vpncustomergateways" :key="item.id" :value="item.id">
{{ item.name }}
</a-select-option>

View File

@ -164,7 +164,8 @@
<a-form-item :label="$t('label.name')">
<a-input
:placeholder="$t('label.unique.name.tier')"
v-decorator="['name',{rules: [{ required: true, message: `${$t('label.required')}` }]}]"></a-input>
v-decorator="['name',{rules: [{ required: true, message: `${$t('label.required')}` }]}]"
autoFocus></a-input>
</a-form-item>
<a-form-item :label="$t('label.networkofferingid')">
<a-select
@ -208,6 +209,7 @@
<a-form @submit.prevent="handleAddInternalLBSubmit" :form="form">
<a-form-item :label="$t('label.name')">
<a-input
autoFocus
:placeholder="$t('label.internallb.name.description')"
v-decorator="['name', { rules: [{ required: true, message: $t('message.error.internallb.name')}] }]"/>
</a-form-item>

View File

@ -30,6 +30,7 @@
</a-tooltip>
</span>
<a-input
autoFocus
v-decorator="['name', {
rules: [{ required: true, message: $t('message.error.required.input') }]
}]"

View File

@ -30,6 +30,7 @@
</a-tooltip>
</span>
<a-input
autoFocus
v-decorator="['name', {
rules: [{ required: true, message: $t('message.error.required.input') }]
}]"

View File

@ -30,6 +30,7 @@
</a-tooltip>
</span>
<a-input
autoFocus
v-decorator="['name', {
rules: [{ required: true, message: $t('message.error.name') }]
}]"

View File

@ -30,6 +30,7 @@
</a-tooltip>
</span>
<a-input
autoFocus
v-decorator="['name', {
rules: [{ required: true, message: $t('message.error.name') }]
}]"

View File

@ -29,6 +29,7 @@
</a-tooltip>
</span>
<a-input
autoFocus
v-decorator="['name', {
rules: [{ required: true, message: $t('message.error.required.input') }]
}]"/>

View File

@ -29,6 +29,7 @@
<a-form-item :label="$t('label.domainid')" v-if="!this.offeringIsPublic">
<a-select
:autoFocus="!this.offeringIsPublic"
mode="multiple"
v-decorator="['domainid', {
rules: [
@ -54,6 +55,7 @@
<a-form-item :label="$t('label.zoneid')">
<a-select
:autoFocus="this.offeringIsPublic"
id="zone-selection"
mode="multiple"
v-decorator="['zoneid', {

View File

@ -36,6 +36,7 @@
@submit="submitTariff">
<a-form-item :label="$t('label.quota.value')">
<a-input
autoFocus
v-decorator="['value', {
rules: [{
required: true,

Some files were not shown because too many files have changed in this diff Show More