From f956658192312223bfeb64204f2e284132af1a3b Mon Sep 17 00:00:00 2001 From: joseflauzino Date: Wed, 4 May 2022 08:15:58 -0300 Subject: [PATCH 1/8] Add VM stats view feature --- ui/package.json | 3 + ui/public/locales/en.json | 35 + ui/public/locales/pt_BR.json | 37 + ui/src/components/view/StatsTab.vue | 663 ++++++++++++++++++ ui/src/components/view/chart/LineChart.vue | 55 ++ ui/src/components/view/stats/FilterStats.vue | 126 ++++ .../view/stats/ResourceStatsInfo.vue | 90 +++ .../{component => components}/dashboard.less | 0 ui/src/style/components/view/StatsTab.scss | 32 + ui/src/views/compute/InstanceTab.vue | 5 + 10 files changed, 1046 insertions(+) create mode 100644 ui/src/components/view/StatsTab.vue create mode 100644 ui/src/components/view/chart/LineChart.vue create mode 100644 ui/src/components/view/stats/FilterStats.vue create mode 100644 ui/src/components/view/stats/ResourceStatsInfo.vue rename ui/src/style/{component => components}/dashboard.less (100%) create mode 100644 ui/src/style/components/view/StatsTab.scss diff --git a/ui/package.json b/ui/package.json index 5d3f2d4ef9d6..d4c9e14e7ead 100644 --- a/ui/package.json +++ b/ui/package.json @@ -42,6 +42,8 @@ "antd-theme-webpack-plugin": "^1.3.9", "axios": "^0.21.1", "babel-plugin-require-context-hook": "^1.0.0", + "chart.js": "^3.7.1", + "chartjs-adapter-moment": "^1.0.0", "core-js": "^3.21.1", "enquire.js": "^2.1.6", "js-cookie": "^2.2.1", @@ -52,6 +54,7 @@ "npm-check-updates": "^6.0.1", "nprogress": "^0.2.0", "vue": "^3.2.31", + "vue-chartjs": "^4.0.7", "vue-clipboard2": "^0.3.1", "vue-cropper": "^1.0.2", "vue-i18n": "^9.1.6", diff --git a/ui/public/locales/en.json b/ui/public/locales/en.json index c81258699719..c65b21fc7eac 100644 --- a/ui/public/locales/en.json +++ b/ui/public/locales/en.json @@ -447,6 +447,7 @@ "label.alerts": "Alerts", "label.algorithm": "Algorithm", "label.all": "All", +"label.all.available.data": "All available data", "label.all.ipv6": "All IPv6", "label.all.zone": "All zones", "label.allocated": "Allocated", @@ -664,6 +665,7 @@ "label.cpu": "CPU", "label.cpu.allocated": "CPU Allocated", "label.cpu.sockets": "CPU sockets", +"label.cpu.usage.info": "CPU usage information", "label.cpuallocated": "CPU allocated for VMs", "label.cpuallocatedghz": "CPU allocated", "label.cpulimit": "CPU limits", @@ -833,6 +835,7 @@ "label.disk.offerings": "Disk offerings", "label.disk.selection": "Disk selection", "label.disk.size": "Disk size", +"label.disk.usage.info": "Disk usage information", "label.disk.volume": "Disk volume", "label.diskbytesreadrate": "Disk read rate (BPS)", "label.diskbyteswriterate": "Disk write rate (BPS)", @@ -935,6 +938,7 @@ "label.enabling.vpn": "Enabling VPN", "label.enabling.vpn.access": "Enabling VPN access", "label.end": "End", +"label.end.date.and.time": "End date and time", "label.end.ip": "End IP", "label.end.reserved.system.ip": "End reserved system IP", "label.end.vlan": "End VLAN", @@ -1436,8 +1440,10 @@ "label.mb.memory": "MB memory", "label.memallocated": "Mem allocation", "label.memory": "Memory", +"label.memory.free": "Memory free", "label.memory.maximum.mb": "Max memory (in MB)", "label.memory.mb": "Memory (in MB)", +"label.memory.usage.info": "Memory usage information", "label.memory.total": "Memory total", "label.memory.used": "Memory used", "label.memoryallocated": "Memory allocated", @@ -1501,6 +1507,8 @@ "label.migrate.to.host": "Migrate to host", "label.migrate.to.storage": "Migrate to storage", "label.migrate.volume": "Migrate volume", +"message.memory.usage.info.hypervisor.additionals": "The data shown may not reflect the actual memory usage if the VM does not have the additional hypervisor tools installed", +"message.memory.usage.info.negative.value": "If the VM's memory usage cannot be obtained from the hypervisor, the lines for free memory in the raw data graph and memory usage in the percentage graph will be disabled", "message.migrate.volume.tooltip": "Volume can be migrated to any suitable storage pool. Admin has to choose the appropriate disk offering to replace, that supports the new storage pool", "label.migrate.volume.newdiskoffering.desc": "This option allows administrators to replace the old disk offering, using one that better suits the new placement of the volume.", "label.migrate.volume.to.primary.storage": "Migrate volume to another primary storage", @@ -1566,6 +1574,7 @@ "label.network.permissions": "Network permissions", "label.network.selection": "Network selection", "label.network.service.providers": "Network service providers", +"label.network.usage.info": "Network usage information", "label.networkcidr": "Network CIDR", "label.networkdevicetype": "Type", "label.networkdomain": "Network domain", @@ -1645,6 +1654,8 @@ "label.offerha": "Offer HA", "label.offeringtype": "Compute offering type", "label.ok": "OK", +"label.only.end.date.and.time": "Only end date and time", +"label.only.start.date.and.time": "Only start date and time", "label.open.documentation": "Open documentation", "label.open.url": "Open URL in browser", "label.opendaylight": "OpenDaylight", @@ -1705,6 +1716,7 @@ "label.pcidevice": "GPU", "label.per.account": "Per account", "label.per.zone": "Per zone", +"label.percentage": "Percentage", "label.perfectforwardsecrecy": "Perfect forward secrecy", "label.perform.fresh.checks": "Perform fresh checks", "label.performfreshchecks": "Perform fresh checks", @@ -1859,12 +1871,14 @@ "label.rados.secret": "RADOS secret", "label.rados.user": "RADOS user", "label.ram": "RAM", +"label.raw.data": "Raw data", "label.rbd": "RBD", "label.rbdid": "Cephx user", "label.rbdmonitor": "Ceph monitor", "label.rbdpool": "Ceph pool", "label.rbdsecret": "Cephx secret", "label.read": "Read", +"label.read.and.write": "Read \u0026 Write", "label.read.io": "Read (IO)", "label.readonly": "Read-Only", "label.reason": "Reason", @@ -2046,6 +2060,10 @@ "label.securitygroups": "Security groups", "label.securitygroupsenabled": "Security groups enabled", "label.select": "Select", +"label.see.more.info.cpu.usage": "See more info about CPU usage", +"label.see.more.info.memory.usage": "See more info about memory usage", +"label.see.more.info.network.usage": "See more info about network usage", +"label.see.more.info.disk.usage": "See more info about disk usage", "label.select-view": "Select view", "label.select.a.zone": "Select a zone", "label.select.deployment.infrastructure": "Select deployment infrastructure", @@ -2055,6 +2073,7 @@ "label.select.iso.or.template": "Select ISO or template", "label.select.network": "Select Network", "label.select.offering": "Select offering", +"label.select.period": "Select period", "label.select.project": "Select project", "label.select.projects": "Select projects", "label.select.ps": "Select primary storage", @@ -2152,6 +2171,7 @@ "label.sslcertificates": "SSL certificates", "label.standard.us.keyboard": "Standard (US) keyboard", "label.start": "Start", +"label.start.date.and.time": "Start date and time", "label.start.ip": "Start IP", "label.start.lb.vm": "Start LB VM", "label.start.reserved.system.ip": "Start reserved system IP", @@ -2466,6 +2486,9 @@ "label.vm.reboot": "Reboot", "label.vm.snapshots": "VM snapshots", "label.vm.start": "Start", +"label.vm.stats.filter.period": "From {startDate} to {endDate}", +"label.vm.stats.filter.starting": "Starting {startDate}.", +"label.vm.stats.filter.up.to": "Up to {endDate}.", "label.vm.stop": "Stop", "label.vmdisplayname": "VM display name", "label.vmfs": "VMFS", @@ -2763,6 +2786,7 @@ "message.advanced.virtual": "Choose this if you wish to use zone-wide VLANs to provide guest VM isolation.", "message.after.enable.s3": "S3-backed secondary storage configured. Note: When you leave this page, you will not be able to re-configure S3 again.", "message.after.enable.swift": "Swift configured. Note: When you leave this page, you will not be able to re-configure Swift again.", +"message.alert.show.all.stats.data": "It can return a lot of data depending on the settings for collecting and retaining stats.", "message.alert.state.detected": "Alert state detected.", "message.allowed": "Allowed", "message.allow.vpn.access": "Please enter a username and password of the user that you want to allow VPN access.", @@ -2880,6 +2904,8 @@ "message.copy.iso.confirm": "Please confirm that you wish to copy your ISO to", "message.copy.template": "Copy template XXX from zone to", "message.copy.template.confirm": "Are you sure you want to copy template?", +"message.cpu.usage.info.multi.cpu": "The percentage of CPU usage can go over 100% when a VM has more than 1 vCPU. This happens because the usage of all the vCPUs of the VM are accumulated.", +"message.cpu.usage.info.cpu.cap": "If a VM has only 1 vCPU and the CPU Cap on its compute offering is disabled, then the percentage of CPU usage can also go over 100%. This happens because the VM can use more CPUs than it has been allocated.", "message.create.compute.offering": "Compute offering created", "message.create.internallb": "Creating internal LB", "message.create.internallb.failed": "Failed to create internal LB.", @@ -2967,6 +2993,8 @@ "message.disallowed.characters": "Disallowed characters: <,>", "message.discovering.feature": "Discovering features, please wait...", "message.disk.offering.created": "Disk offering created:", +"message.disk.usage.info.data.points": "Each data point represents the difference in read/write data since the last data point.", +"message.disk.usage.info.sum.of.disks": "The disk usage shown is made up of the sum of read/write data from all the disks in the VM.", "message.download.diagnostics": "Please click the link to download the retrieved diagnostics:

00000", "message.download.iso": "Please click the link to download the ISO:

00000", "message.download.template": "Please click the link to download the template:

00000", @@ -3021,6 +3049,7 @@ "message.error.display.text": "Please enter display text.", "message.error.domain": "Enter your domain, leave empty for ROOT domain.", "message.error.enable.saml": "Unable to find users IDs to enable SAML single sign on, kindly enable it manually.", +"message.error.end.date.and.time": "Please select the end date and time!", "message.error.endip": "Please enter end IP.", "message.error.gateway": "Please enter gateway.", "message.error.host.name": "Please enter host name.", @@ -3093,6 +3122,7 @@ "message.error.smb.username": "Please enter SMB username.", "message.error.specify.sticky.name": "Please specify a sticky name.", "message.error.sr.namelabel": "Please enter SR Name-Label.", +"message.error.start.date.and.time": "Please select the start date and time!", "message.error.startip": "Please enter start IP.", "message.error.storage.tags": "Please enter storage tags.", "message.error.target.iqn": "Please enter target IQN.", @@ -3251,8 +3281,11 @@ "message.network.removenic": "Please confirm that want to remove this NIC, which will also remove the associated network from the VM.", "message.network.secondaryip": "Please confirm that you would like to acquire a new secondary IP for this NIC. \n NOTE: You need to manually configure the newly-acquired secondary IP inside the virtual machine.", "message.network.updateip": "Please confirm that you would like to change the IP address for this NIC on VM.", +"message.network.usage.info.data.points": "Each data point represents the difference in data traffic since the last data point.", +"message.network.usage.info.sum.of.vnics": "The network usage shown is made up of the sum of data traffic from all the vNICs in the VM.", "message.new.user": "Specify the following to add a new user to the account", "message.no.affinity.groups": "You do not have any affinity groups. Please continue to the next step.", +"message.no.data.to.show.for.period": "No data to show for the selected period.", "message.no.datadisk": "The multidisk template has no data disk, please continue to next step.", "message.no.description": "No description entered.", "message.no.host.available": "No hosts are available for migration.", @@ -3361,12 +3394,14 @@ "message.select.affinity.groups": "Please select any affinity groups you want this VM to belong to:", "message.select.destination.image.stores": "Please select Image Store(s) to which data is to be migrated to", "message.select.disk.offering": "Please select a disk offering for disk", +"message.select.end.date.and.time": "Select an end date & time.", "message.select.instance": "Please select an instance.", "message.select.iso": "Please select an ISO for your new virtual instance.", "message.select.item": "Please select an item.", "message.select.migration.policy": "Please select a migration policy.", "message.select.nic.network": "Please select a network for NIC", "message.select.security.groups": "Please select security group(s) for your new VM.", +"message.select.start.date.and.time": "Select a start date & time.", "message.select.template": "Please select a template for your new virtual instance.", "message.select.tier": "Please select a tier.", "message.select.zone.description": "Select type of zone basic/advanced.", diff --git a/ui/public/locales/pt_BR.json b/ui/public/locales/pt_BR.json index b006238cc3d1..e777eab2d0fc 100644 --- a/ui/public/locales/pt_BR.json +++ b/ui/public/locales/pt_BR.json @@ -372,6 +372,7 @@ "label.alerts": "Alertas", "label.algorithm": "Algoritmo", "label.all": "Todos", +"label.all.available.data": "Todos os dados dispon\u00edveis", "label.allocated": "Alocado", "label.allocationstate": "Status da Aloca\u00e7\u00e3o", "label.allow": "Pertitir", @@ -504,6 +505,7 @@ "label.cpu": "CPU", "label.cpu.allocated": "CPU Alocada", "label.cpu.sockets": "Sockets", +"label.cpu.usage.info": "Informa\u00e7\u00f5es sobre o uso de CPU", "label.cpuallocated": "CPU Alocada por VMs", "label.cpuallocatedghz": "Alocado", "label.cpulimit": "Limite de CPU", @@ -614,6 +616,7 @@ "label.disk.offering.details": "Detalhes da oferta de disco", "label.disk.offerings": "Oferta de Discos", "label.disk.size": "Tamanho do Disco", +"label.disk.usage.info": "Informa\u00e7\u00f5es sobre o uso de disco", "label.disk.volume": "Disco", "label.diskbytesreadrate": "Taxa de Leitura do Disco (BPS)", "label.diskbyteswriterate": "Taxa de Escrita no Disco (BPS)", @@ -692,6 +695,7 @@ "label.enable.vpn": "Habilitar VPN", "label.enabling.vpn": "Ativando VPN", "label.enabling.vpn.access": "Ativando Acesso VPN", +"label.end.date.and.time": "Data e hor\u00e1rio final", "label.end.ip": "IP do fim", "label.end.reserved.system.ip": "Fim dos IPs reservados para o sistema", "label.end.vlan": "VLAN final", @@ -732,6 +736,7 @@ "label.firstname.lower": "primeiro nome", "label.forceencap": "For\u00e7ar encapsulamento UDP de pacotes ESP", "label.format": "Formato", +"label.free": "Livre", "label.friday": "Sexta-feira", "label.full": "Full", "label.full.path": "Path completo", @@ -1037,7 +1042,9 @@ "label.may.continue": "Voc\u00ea pode continuar agora", "label.memallocated": "Aloca\u00e7\u00e3o de Mem\u00f3ria", "label.memory": "Mem\u00f3ria (em MB)", +"label.memory.free": "Mem\u00f3ria Livre", "label.memory.total": "Mem\u00f3ria Total", +"label.memory.usage.info": "Informa\u00e7\u00f5es sobre o uso de mem\u00f3ria", "label.memory.used": "Mem\u00f3ria Usada", "label.memoryallocated": "Mem\u00f3ria Alocada", "label.memoryallocatedgb": "Alocado", @@ -1134,6 +1141,7 @@ "label.network.offering.name": "Network Offering Name", "label.network.offerings": "Oferta de Rede", "label.network.service.providers": "Provedores de Servi\u00e7os de Rede", +"label.network.usage.info": "Informa\u00e7\u00f5es sobre o uso de rede", "label.networkcidr": "CIDR da Rede", "label.networkdevicetype": "Tipo", "label.networkdomain": "Dom\u00ednio de Rede", @@ -1199,6 +1207,8 @@ "label.of.month": "do m\u00eas", "label.offerha": "Offer HA", "label.ok": "OK", +"label.only.end.date.and.time": "Apenas data e hor\u00e1rio final", +"label.only.start.date.and.time": "Apenas data e hor\u00e1rio inicial", "label.opendaylight": "OpenDaylight", "label.opendaylight.controller": "Controlador OpenDaylight", "label.opendaylight.controllerdetail": "Detalhes do Controlador OpenDaylight", @@ -1241,6 +1251,7 @@ "label.patp": "Palo Alto Threat Profile", "label.pavr": "Roteador Virtual", "label.pcidevice": "GPU", +"label.percentage": "Porcentagem", "label.perfectforwardsecrecy": "Perfect Forward Secrecy", "label.permission": "Permiss\u00e3o", "label.physical.network": "Rede F\u00edsica", @@ -1357,11 +1368,13 @@ "label.quota.tariff.effectivedate": "Data Efetiva", "label.quota.totalusage": "Uso Total", "label.quota.usage": "Consumo da Cota", +"label.raw.data": "Dados Brutos", "label.rbd": "RDB", "label.rbdid": "Usu\u00e1rio Ceph", "label.rbdmonitor": "Monitor Ceph", "label.rbdpool": "Pool Ceph", "label.rbdsecret": "Cephx secret", +"label.read.and.write": "Leitura & Escrita", "label.reason": "Motivo", "label.reboot": "Reiniciar", "label.receivedbytes": "Bytes Recebidos", @@ -1497,6 +1510,10 @@ "label.security.groups.enabled": "Security Groups Ativado", "label.securitygroup": "Security Group", "label.securitygroups": "Grupos de seguran\u00e7a", +"label.see.more.info.cpu.usage": "Ver mais informa\u00e7\u00f5es sobre o uso de CPU", +"label.see.more.info.memory.usage": "Ver mais informa\u00e7\u00f5es sobre o uso de mem\u00f3ria", +"label.see.more.info.network.usage": "Ver mais informa\u00e7\u00f5es sobre o uso de rede", +"label.see.more.info.disk.usage": "Ver mais informa\u00e7\u00f5es sobre o uso de disco", "label.select": "Selecionar", "label.select-view": "Selecionar visualiza\u00e7\u00e3o", "label.select.a.zone": "Selecione uma zona", @@ -1504,6 +1521,7 @@ "label.select.instance.to.attach.volume.to": "Escolha uma inst\u00e2ncia para conectar o volume", "label.select.iso.or.template": "Selecione ISO ou template", "label.select.offering": "Selecionar Oferta", +"label.select.period": "Selecionar per\u00edodo", "label.select.project": "Selecionar Projeto", "label.select.region": "Selecione Regi\u00e3o", "label.select.tier": "Selecione camada", @@ -1578,6 +1596,7 @@ "label.ssh.key.pairs": "Par de chaves SSH", "label.sshkeypair": "Novo par de chaves SSH", "label.standard.us.keyboard": "Standard (US) keyboard", +"label.start.date.and.time": "Data e hor\u00e1rio inicial", "label.start.ip": "IP do in\u00edcio", "label.start.lb.vm": "Iniciar LB VM", "label.start.reserved.system.ip": "In\u00edcio dos IPs reservados para o sistema", @@ -1723,6 +1742,7 @@ "label.usageunit": "Unidade", "label.use.vm.ip": "Usar IP da VM:", "label.use.vm.ips": "Usa IPs da VM", +"label.used": "Utilizado", "label.usehttps": "Use HTTPS", "label.usenewdiskoffering": "Replace disk offering?", "label.user": "Usu\u00e1rio", @@ -1792,6 +1812,9 @@ "label.vm.reboot": "Reiniciar", "label.vm.snapshots": "Snapshot da VM", "label.vm.start": "In\u00edcio", +"label.vm.stats.filter.period": "De {startDate} at\u00e9 {endDate}.", +"label.vm.stats.filter.starting": "A partir de {startDate}.", +"label.vm.stats.filter.up.to": "At\u00e9 {endDate}.", "label.vm.stop": "Parar", "label.vmdisplayname": "Nome de exibi\u00e7\u00e3o da VM", "label.vmfs": "VMFS", @@ -1995,6 +2018,7 @@ "message.advanced.virtual": "Escolha esta op\u00e7\u00e3o se desejar utilizar VLANs para isolamento das VMs guest.", "message.after.enable.s3": "Storage secund\u00e1ria fornecida por S3 configurada. Nota: ao deixar esta p\u00e1gina, voc\u00ea n\u00e3o ser\u00e1 capaz de reconfigurar S3 novamente.", "message.after.enable.swift": "Swift Configurado. Nota: Ap\u00f3s deixar esta p\u00e1gina, voc\u00ea n\u00e3o ser\u00e1 capaz de reconfigurar o Swift novamente.", +"message.alert.show.all.stats.data": "Isso pode retornar muitos dados dependendo das configura\u00e7\u00f5es de coleta e reten\u00e7\u00e3o de estat\u00edsticas.", "message.alert.state.detected": "Alerta de estado detectado", "message.allow.vpn.access": "Entre com nome de Usu\u00e1rio e senha do Usu\u00e1rio que ter\u00e1 acesso VPN.", "message.apply.snapshot.policy": "Voc\u00ea atualizou com sucesso sua pol\u00edtica de Snapshot.", @@ -2083,6 +2107,8 @@ "message.copy.iso.confirm": "Confirme se voc\u00ea deseja copiar a ISO para", "message.copy.template": "Copiar template XXX da zona para", "message.copy.template.confirm": "Voc\u00ea tem certeza que deseja copiar o template ?", +"message.cpu.usage.info.multi.cpu": "O percentual de uso de CPU pode passar de 100% quando uma VM possui mais de 1 vCPU. Isso ocorre porque \u00e9 feito o somat\u00f3rio do uso de todos os CPUs da VM", +"message.cpu.usage.info.cpu.cap": "Se uma VM possui apenas 1 vCPU e o CPU Cap da oferta de computa\u00e7\u00e3o estiver desabilitado, o percentual de uso de CPU tamb\u00e9m pode passar de 100%. Isso porque a VM pode utilizar mais CPUs do que lhe foi atribu\u00eddo", "message.create.template": "Voc\u00ea tem certeza que deseja criar um template ?", "message.create.template.vm": "Criar VM do template ", "message.create.template.volume": "Especifique as seguintes informa\u00e7\u00f5es antes de criar o template a partir do disco: . A cria\u00e7\u00e3o de um template a partir de um disco pode levar alguns minutos ou mais dependendo do tamnho do disco.", @@ -2125,6 +2151,8 @@ "message.disabling.network.offering": "Desabilita oferta de rede", "message.disabling.vpc.offering": "Desabilitando oferta VPC", "message.disallowed.characters": "Caracteres n\u00e3o-permitidos: <,>", +"message.disk.usage.info.data.points": "Cada ponto no gr\u00e1fico representa a diferen\u00e7a de dados lidos/escritos desde a \u00faltima coleta de estat\u00edstica realizada (o ponto anterior)", +"message.disk.usage.info.sum.of.disks": "O uso de disco apresentado \u00e9 composto pela soma de dados lidos/escritos por todos os discos da VM", "message.download.iso": "Por favor clique 00000 para baixar o ISO", "message.download.template": "Por favor clique 00000 para baixar o template", "message.download.volume": "Clique 00000 para baixar o disco", @@ -2146,7 +2174,9 @@ "message.enabling.zone.dots": "Habilitando Zona....", "message.enter.seperated.list.multiple.cidrs": "Por favor entre a de CIDRs separadas por v\u00edrgula, se houver mais de uma", "message.enter.token": "Por favor entre o token que voc\u00ea recebeu no e-mail privado.", +"message.error.end.date.and.time": "Por favor, selecione a data e hor\u00e1rio final!", "message.error.fixed.offering.kvm": "Não é possível escalar VMs que utilizam o hipervisor KVM com oferta de computa\u00e7\u00e3o fixa.", +"message.error.start.date.and.time": "Por favor, selecione a data e hor\u00e1rio inicial!", "message.generate.keys": "Por favor confirme que voc\u00ea deseja gerar novas chaves para este usu\u00e1rio.", "message.gslb.delete.confirm": "Confirme que voc\u00ea deseja apagar este GSLB", "message.gslb.lb.remove.confirm": "Confirme que voc\u00ea deseja remover o balanceamento de carga deste GSLB", @@ -2199,6 +2229,8 @@ "message.link.domain.to.ldap": "Ativar sincroniza\u00e7\u00e3o autom\u00e1tica para este dom\u00ednio em LDAP", "message.listview.subselect.multi": "(Ctrl/Cmd-click)", "message.lock.account": "Confirme se voc\u00ea deseja bloquear esta conta. Bloqueando a conta, todos os Usu\u00e1rios desta conta n\u00e3o estar\u00e3o mais habilitados a gerenciar os recursos na nuvem. Os recursos existentes (Cloud Server) ainda poder\u00e3o ser acessados.", +"message.memory.usage.info.hypervisor.additionals": "Os dados apresentados podem n\u00e3o refletir o real uso de mem\u00f3ria se a VM n\u00e3o possuir as ferramentas adicionais do virtualizador instaladas", +"message.memory.usage.info.negative.value": "Se n\u00e3o for poss\u00edvel obter do hypervisor o uso de mem\u00f3ria da VM, ser\u00e3o desabilitadas as linhas de mem\u00f3ria livre do gr\u00e1fico de dados brutos e de uso de mem\u00f3ria no gr\u00e1fico de percentual", "message.migrate.instance.confirm": "Confirme o host que voc\u00ea deseja migrar a inst\u00e2ncia virtual.", "message.migrate.instance.to.host": "Por favor confirme que voc\u00ea deseja migrar a inst\u00e2ncia para outro host.", "message.migrate.instance.to.ps": "Por favor confirme que voc\u00ea deseja migrar a inst\u00e2ncia para outro storage prim\u00e1rio.", @@ -2210,8 +2242,11 @@ "message.network.remote.access.vpn.configuration": "A configura\u00e7\u00e3o de acesso remoto VPN foi gerada, mas falhou ao ser aplicada. Por favor, verifique a conectividade dos elementos de rede e depois tente novamente.", "message.network.removenic": "Por favor, confirme que deseja remover esta Interface de Rede, esta a\u00e7\u00e3o tamb\u00e9m ir\u00e1 remover a rede associada \u00e0 VM.", "message.network.updateip": "Por favor, confirme que voc\u00ea gostaria de mudar o endere\u00e7o IP da NIC em VM.", +"message.network.usage.info.data.points": "Cada ponto no gr\u00e1fico representa a diferen\u00e7a de dados trafegados desde a \u00faltima coleta de estat\u00edstica realizada (o ponto anterior)", +"message.network.usage.info.sum.of.vnics": "O uso de rede apresentado \u00e9 composto pela soma de dados trafegados por todas as vNICs da VM", "message.new.user": "Especifique abaixo para adicionar novos usu\u00e1rios para a conta", "message.no.affinity.groups": "Voc\u00ea n\u00e3o tem nenhum grupo de afinidade. Por favor, v\u00e1 para o pr\u00f3ximo passo.", +"message.no.data.to.show.for.period": "Nenhum dado para mostrar no per\u00edodo selecionado.", "message.no.host.available": "Sem hosts dispon\u00edveis para Migra\u00e7\u00e3o", "message.no.network.support": "O hypervisor escolhido, vSphere, n\u00e3o possui nenhum recurso de rede adicional. Por favor, v\u00e1 para o passo 5.", "message.no.network.support.configuration.not.true": "Voc\u00ea n\u00e3o possui nenhuma zona com grupos de seguran\u00e7a habilitado. Assim sendo, n\u00e3o possui recursos adicionais de rede. Por favor continue para o passo 5.", @@ -2264,10 +2299,12 @@ "message.security.group.usage": "(Use Ctrl-clique para selecionar todos os Security Groups)", "message.select.a.zone": "A zone tipicamente corresponde a um \u00fanico datacenter. M\u00faltiplas zonas auxiliam a cloud a ser mais confi\u00e1vel provendo isolamento f\u00edsico e redund\u00e2ncia.", "message.select.affinity.groups": "Por favor, selecione quaisquer grupos de afinidade que voc\u00ea deseja que esta VM perten\u00e7a:", +"message.select.end.date.and.time": "Select an end date & time.", "message.select.instance": "Por favor selecione uma inst\u00e2ncia.", "message.select.iso": "Por favor selecione um ISO para sua nova inst\u00e2ncia virtual", "message.select.item": "Por favor selecione um item.", "message.select.security.groups": "Por favor selecione o(s) grupo(s) de seguran\u00e7a para sua nova VM", +"message.select.start.date.and.time": "Selecione uma data e hor\u00e1rio inicial.", "message.select.template": "Por favor selecione um template para sua nova inst\u00e2ncia virtual.", "message.select.tier": "Por favor, selecione um tier", "message.set.default.nic": "Por favor confirme que voc\u00ea quer tornar este NIC o padr\u00e3o para esta VM,", diff --git a/ui/src/components/view/StatsTab.vue b/ui/src/components/view/StatsTab.vue new file mode 100644 index 000000000000..7269298fe924 --- /dev/null +++ b/ui/src/components/view/StatsTab.vue @@ -0,0 +1,663 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + + + + + diff --git a/ui/src/components/view/chart/LineChart.vue b/ui/src/components/view/chart/LineChart.vue new file mode 100644 index 000000000000..1b9206917d76 --- /dev/null +++ b/ui/src/components/view/chart/LineChart.vue @@ -0,0 +1,55 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + + + + diff --git a/ui/src/components/view/stats/FilterStats.vue b/ui/src/components/view/stats/FilterStats.vue new file mode 100644 index 000000000000..d9ec31847c59 --- /dev/null +++ b/ui/src/components/view/stats/FilterStats.vue @@ -0,0 +1,126 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + + + + diff --git a/ui/src/components/view/stats/ResourceStatsInfo.vue b/ui/src/components/view/stats/ResourceStatsInfo.vue new file mode 100644 index 000000000000..e6f0d0680082 --- /dev/null +++ b/ui/src/components/view/stats/ResourceStatsInfo.vue @@ -0,0 +1,90 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + + + + diff --git a/ui/src/style/component/dashboard.less b/ui/src/style/components/dashboard.less similarity index 100% rename from ui/src/style/component/dashboard.less rename to ui/src/style/components/dashboard.less diff --git a/ui/src/style/components/view/StatsTab.scss b/ui/src/style/components/view/StatsTab.scss new file mode 100644 index 000000000000..89e51ab0cb95 --- /dev/null +++ b/ui/src/style/components/view/StatsTab.scss @@ -0,0 +1,32 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +.ant-tag { + padding: 0 7px 0 0; +} +.ant-select { + margin-left: 10px; +} +.info-icon { + margin: 0 10px 0 5px; +} +.chart-row { + margin-bottom: 10%; +} +.chart-type-select { + min-width: 130px; +} diff --git a/ui/src/views/compute/InstanceTab.vue b/ui/src/views/compute/InstanceTab.vue index 9e4e84ff1fc0..ec6c7c322999 100644 --- a/ui/src/views/compute/InstanceTab.vue +++ b/ui/src/views/compute/InstanceTab.vue @@ -25,6 +25,9 @@ + + + {{ vm.isoname }}
@@ -307,6 +310,7 @@ import { mixinDevice } from '@/utils/mixin.js' import ResourceLayout from '@/layouts/ResourceLayout' import Status from '@/components/widgets/Status' import DetailsTab from '@/components/view/DetailsTab' +import StatsTab from '@/components/view/StatsTab' import EventsTab from '@/components/view/EventsTab' import DetailSettings from '@/components/view/DetailSettings' import NicsTable from '@/views/network/NicsTable' @@ -320,6 +324,7 @@ export default { components: { ResourceLayout, DetailsTab, + StatsTab, EventsTab, DetailSettings, NicsTable, From ab4e1b90b94c53730df5d02ba95d64493039779c Mon Sep 17 00:00:00 2001 From: joseflauzino Date: Fri, 3 Jun 2022 16:29:09 -0300 Subject: [PATCH 2/8] Add dynamic label to the submit button of the VM stats filtering modal --- ui/src/components/view/stats/FilterStats.vue | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/ui/src/components/view/stats/FilterStats.vue b/ui/src/components/view/stats/FilterStats.vue index d9ec31847c59..2a36631b0bfc 100644 --- a/ui/src/components/view/stats/FilterStats.vue +++ b/ui/src/components/view/stats/FilterStats.vue @@ -55,7 +55,7 @@

{{ $t('label.cancel') }} - {{ $t('label.ok') }} + {{ submitButtonLabel }}
@@ -73,7 +73,8 @@ export default { showAllDataAlert: false, showAllData: true, showStartDate: true, - showEndDate: true + showEndDate: true, + submitButtonLabel: this.$t('label.ok') } }, created () { @@ -90,6 +91,7 @@ export default { handleSubmit (e) { e.preventDefault() this.formRef.value.validate().then(() => { + this.submitButtonLabel = this.$t('label.refresh') const values = toRaw(this.form) this.$emit('onSubmit', values) }).catch(error => { @@ -108,18 +110,24 @@ export default { this.showStartDate = true this.showEndDate = true } + this.resetSubmitButton() }, onToggleStartDate () { this.showEndDate = !this.showEndDate if (this.showEndDate === false) { this.form.endDate = null } + this.resetSubmitButton() }, onToggleEndDate () { this.showStartDate = !this.showStartDate if (this.showStartDate === false) { this.form.startDate = null } + this.resetSubmitButton() + }, + resetSubmitButton () { + this.submitButtonLabel = this.$t('label.ok') } } } From 46fe0bc07f3edff65d8d9d92e0efebac9cb95e16 Mon Sep 17 00:00:00 2001 From: joseflauzino Date: Thu, 23 Jun 2022 11:06:52 -0300 Subject: [PATCH 3/8] Improve CPU info message --- ui/public/locales/en.json | 2 +- ui/public/locales/pt_BR.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/public/locales/en.json b/ui/public/locales/en.json index c65b21fc7eac..bb6c2c1a858b 100644 --- a/ui/public/locales/en.json +++ b/ui/public/locales/en.json @@ -2904,7 +2904,7 @@ "message.copy.iso.confirm": "Please confirm that you wish to copy your ISO to", "message.copy.template": "Copy template XXX from zone to", "message.copy.template.confirm": "Are you sure you want to copy template?", -"message.cpu.usage.info.multi.cpu": "The percentage of CPU usage can go over 100% when a VM has more than 1 vCPU. This happens because the usage of all the vCPUs of the VM are accumulated.", +"message.cpu.usage.info.multi.cpu": "The CPU usage percentage can exceed 100% if the VM has more than 1 vCPU or when CPU Cap is not enabled. This behavior happens according to how the hypervisor being used accounts the stats.", "message.cpu.usage.info.cpu.cap": "If a VM has only 1 vCPU and the CPU Cap on its compute offering is disabled, then the percentage of CPU usage can also go over 100%. This happens because the VM can use more CPUs than it has been allocated.", "message.create.compute.offering": "Compute offering created", "message.create.internallb": "Creating internal LB", diff --git a/ui/public/locales/pt_BR.json b/ui/public/locales/pt_BR.json index e777eab2d0fc..e7c22bae033f 100644 --- a/ui/public/locales/pt_BR.json +++ b/ui/public/locales/pt_BR.json @@ -2107,7 +2107,7 @@ "message.copy.iso.confirm": "Confirme se voc\u00ea deseja copiar a ISO para", "message.copy.template": "Copiar template XXX da zona para", "message.copy.template.confirm": "Voc\u00ea tem certeza que deseja copiar o template ?", -"message.cpu.usage.info.multi.cpu": "O percentual de uso de CPU pode passar de 100% quando uma VM possui mais de 1 vCPU. Isso ocorre porque \u00e9 feito o somat\u00f3rio do uso de todos os CPUs da VM", +"message.cpu.usage.info.multi.cpu": "O percentual de uso de CPU pode passar de 100% quando uma VM possui mais de 1 vCPU. Isso pode acontecer dependendo da forma que o virtualizador contabiliza as estat\u00edsticas.", "message.cpu.usage.info.cpu.cap": "Se uma VM possui apenas 1 vCPU e o CPU Cap da oferta de computa\u00e7\u00e3o estiver desabilitado, o percentual de uso de CPU tamb\u00e9m pode passar de 100%. Isso porque a VM pode utilizar mais CPUs do que lhe foi atribu\u00eddo", "message.create.template": "Voc\u00ea tem certeza que deseja criar um template ?", "message.create.template.vm": "Criar VM do template ", From 5108fde29571f0a40824078f66d34b26b848163a Mon Sep 17 00:00:00 2001 From: joseflauzino Date: Thu, 23 Jun 2022 11:07:53 -0300 Subject: [PATCH 4/8] Reduce identation --- ui/src/components/view/StatsTab.vue | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/ui/src/components/view/StatsTab.vue b/ui/src/components/view/StatsTab.vue index 7269298fe924..55b0fdb85458 100644 --- a/ui/src/components/view/StatsTab.vue +++ b/ui/src/components/view/StatsTab.vue @@ -521,16 +521,13 @@ export default { * @returns the percentage of used/free memory. */ calculateMemoryPercentage (isUsed, memoryTotalInKB, memoryFreeInKB) { - var percentage = -1 - if (memoryTotalInKB != null && memoryFreeInKB != null) { - if (isUsed) { - percentage = parseFloat(100.0 * (memoryTotalInKB - memoryFreeInKB) / memoryTotalInKB).toFixed(2) - return percentage - } - percentage = parseFloat(100.0 * memoryFreeInKB / memoryTotalInKB).toFixed(2) - return percentage + if (memoryTotalInKB == null || memoryFreeInKB == null) { + return -1 + } + if (isUsed) { + return parseFloat(100.0 * (memoryTotalInKB - memoryFreeInKB) / memoryTotalInKB).toFixed(2) } - return percentage + return parseFloat(100.0 * memoryFreeInKB / memoryTotalInKB).toFixed(2) }, /** * Calculates the maximum Y axis and the step size based on the chart data. From 72ab9eefee6502cf879c2086348614fc19875dd6 Mon Sep 17 00:00:00 2001 From: joseflauzino Date: Sat, 6 Aug 2022 17:11:00 -0300 Subject: [PATCH 5/8] Remove missed line --- ui/public/locales/pt_BR.json | 1 - 1 file changed, 1 deletion(-) diff --git a/ui/public/locales/pt_BR.json b/ui/public/locales/pt_BR.json index 267dc0de2021..88972c5da10b 100644 --- a/ui/public/locales/pt_BR.json +++ b/ui/public/locales/pt_BR.json @@ -2177,7 +2177,6 @@ "message.failed.to.add": "Falha ao adicionar", "message.failed.to.assign.vms": "Falha ao atribuir VMs", "message.failed.to.remove": "Falha ao remover", ->>>>>>> main "message.generate.keys": "Por favor confirme que voc\u00ea deseja gerar novas chaves para este usu\u00e1rio.", "message.guest.traffic.in.advanced.zone": "O tr\u00e1fego de rede guest \u00e9 para comunica\u00e7\u00e3o entre m\u00e1quinas virtuais do usu\u00e1rio final. Especifique um intervalo de IDs de VLAN para transportar o tr\u00e1fego do guest para cada rede f\u00edsica.", "message.guest.traffic.in.basic.zone": "O tr\u00e1fego de rede guest \u00e9 para comunica\u00e7\u00e3o entre m\u00e1quinas virtuais do usu\u00e1rio final. Especifique um intervalo de endere\u00e7os IP para que CloudStack possa atribuir \u00e0s VMs. Certifique-se que este intervalo n\u00e3o se sobreponha o range de IPs reservados do sistema.", From ddac3604ad330599e491ce5d3a0e28e0a9457903 Mon Sep 17 00:00:00 2001 From: joseflauzino Date: Sat, 6 Aug 2022 17:13:30 -0300 Subject: [PATCH 6/8] Fix timestamp when 'Use local timezone' is selected --- ui/src/components/view/StatsTab.vue | 3 ++- ui/src/utils/plugins.js | 12 ++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/ui/src/components/view/StatsTab.vue b/ui/src/components/view/StatsTab.vue index 55b0fdb85458..aa6cb5c1d2a0 100644 --- a/ui/src/components/view/StatsTab.vue +++ b/ui/src/components/view/StatsTab.vue @@ -398,7 +398,8 @@ export default { const diskIopsLine = { label: 'IOPS', backgroundColor: blueInRgba, borderColor: blue, data: [], pointRadius: chartPointRadius } for (const element of vm[0].stats) { - const currentLabel = element.timestamp.split('T')[0] + ' ' + element.timestamp.split('T')[1].split('-')[0] + var ts = this.$toLocalDate(element.timestamp) + const currentLabel = ts.split('T')[0] + ' ' + ts.split('T')[1].split('-')[0] this.chartLabels.push(currentLabel) cpuLine.data.push({ timestamp: currentLabel, stat: element.cpuused.split('%')[0] }) diff --git a/ui/src/utils/plugins.js b/ui/src/utils/plugins.js index 63a0e609c5d1..35a95646917d 100644 --- a/ui/src/utils/plugins.js +++ b/ui/src/utils/plugins.js @@ -305,6 +305,18 @@ export const toLocaleDatePlugin = { dateWithOffset = dateWithOffset.substring(0, dateWithOffset.length - 4) return dateWithOffset } + + app.config.globalProperties.$toLocalDate = function (date) { + var timezoneOffset = this.$store.getters.timezoneoffset + if (this.$store.getters.usebrowsertimezone) { + // Since GMT+530 is returned as -330 (mins to GMT) + timezoneOffset = new Date().getTimezoneOffset() / -60 + } + var milliseconds = Date.parse(date) + // e.g. "Tue, 08 Jun 2010 19:13:49 GMT", "Tue, 25 May 2010 12:07:01 UTC" + var dateWithOffset = new Date(milliseconds + (timezoneOffset * 60 * 60 * 1000)) + return dateWithOffset.toISOString() + } } } From 560407a3e58c1eb093809b71f19bf7643bc43bae Mon Sep 17 00:00:00 2001 From: joseflauzino Date: Mon, 8 Aug 2022 11:22:47 -0300 Subject: [PATCH 7/8] Fix bug when filtering for all data --- ui/src/components/view/stats/FilterStats.vue | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ui/src/components/view/stats/FilterStats.vue b/ui/src/components/view/stats/FilterStats.vue index 2a36631b0bfc..50452d776e45 100644 --- a/ui/src/components/view/stats/FilterStats.vue +++ b/ui/src/components/view/stats/FilterStats.vue @@ -106,6 +106,8 @@ export default { if (this.showAllDataAlert) { this.showStartDate = false this.showEndDate = false + this.form.startDate = null + this.form.endDate = null } else { this.showStartDate = true this.showEndDate = true From 12787ba291909018de65e79f19575b3c4dad6ebb Mon Sep 17 00:00:00 2001 From: joseflauzino Date: Wed, 24 Aug 2022 13:35:43 -0300 Subject: [PATCH 8/8] Support for toggle 'Use local timezone' button --- ui/src/components/view/StatsTab.vue | 65 ++++++++++++++++++-- ui/src/components/view/stats/FilterStats.vue | 33 +++++++++- 2 files changed, 90 insertions(+), 8 deletions(-) diff --git a/ui/src/components/view/StatsTab.vue b/ui/src/components/view/StatsTab.vue index aa6cb5c1d2a0..60d5793f8b59 100644 --- a/ui/src/components/view/StatsTab.vue +++ b/ui/src/components/view/StatsTab.vue @@ -23,6 +23,8 @@ :maskClosable="false" :footer="null"> @@ -233,8 +235,8 @@ export default { loaded: false, showCpuInfo: false, showFilterStatsModal: false, - endDate: new Date(), - startDate: new Date().setHours(new Date().getHours() - 1), + endDate: this.getEndDate(), + startDate: this.getStartDate(), formatedPeriod: null, selectedMemoryChartType: 0, selectedMemoryUsageType: 0, @@ -286,12 +288,26 @@ export default { mounted () { this.fetchData() }, + computed: { + usebrowsertimezone: function () { + return this.$store.getters.usebrowsertimezone + } + }, watch: { resource: function (newItem) { if (!newItem || !newItem.id) { return } this.fetchData() + }, + usebrowsertimezone: function () { + if (this.startDate) { + this.startDate = this.onToggleUseBrowserTimezone(new Date(this.startDate)) + } + if (this.endDate) { + this.endDate = this.onToggleUseBrowserTimezone(new Date(this.endDate)) + } + this.fetchData() } }, methods: { @@ -317,24 +333,61 @@ export default { this.showResourceInfoModal = true }, handleSubmit (values) { - this.startDate = values.startDate - this.endDate = values.endDate + if (values.startDate) { + this.startDate = new Date(values.startDate) + } else { + this.startDate = null + } + if (values.endDate) { + this.endDate = new Date(values.endDate) + } else { + this.endDate = null + } this.showFilterStatsModal = false this.fetchData() }, closeAction () { this.showFilterStatsModal = false }, + getStartDate () { + var now = new Date() + if (!this.$store.getters.usebrowsertimezone) { + var dateInUTC = new Date(now.getTime() + now.getTimezoneOffset() * 60000) + return dateInUTC.setHours(dateInUTC.getHours() - 1) + } + now.setHours(now.getHours() - 1) + return now + }, + getEndDate () { + var now = new Date() + if (this.$store.getters.usebrowsertimezone) { + return now + } + return new Date(now.getTime() + now.getTimezoneOffset() * 60000) + }, + onToggleUseBrowserTimezone (date) { + if (this.$store.getters.usebrowsertimezone) { + return this.$toLocalDate(date) + } + return new Date(date.getTime() + date.getTimezoneOffset() * 60000) + }, + convertAndFormatDateAppropriately (date) { + if (this.$store.getters.usebrowsertimezone) { + var dateInUTC = new Date(date).toISOString().split('T') + return dateInUTC[0] + ' ' + dateInUTC[1].split('-')[0].split('.')[0] + } + return moment(date).format('YYYY-MM-DD HH:mm:ss') + }, fetchData () { this.loaded = false this.showResourceInfoModal = false this.formatPeriod() var params = { id: this.resource.id } if (this.startDate) { - params.startDate = moment(this.startDate).format('YYYY-MM-DD HH:mm:ss') + params.startDate = this.convertAndFormatDateAppropriately(this.startDate) } if (this.endDate) { - params.endDate = moment(this.endDate).format('YYYY-MM-DD HH:mm:ss') + params.endDate = this.convertAndFormatDateAppropriately(this.endDate) } api('listVirtualMachinesUsageHistory', params).then(response => { this.handleStatsResponse(response) diff --git a/ui/src/components/view/stats/FilterStats.vue b/ui/src/components/view/stats/FilterStats.vue index 50452d776e45..20cd63af873d 100644 --- a/ui/src/components/view/stats/FilterStats.vue +++ b/ui/src/components/view/stats/FilterStats.vue @@ -61,10 +61,35 @@