OvhKvm/servicesview.cpp

154 lines
7.0 KiB
C++

#include "servicesview.h"
#include "ui_servicesview.h"
#include "ovhapi.h"
#include <QDebug>
#include <QTimer>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QPushButton>
#include <QComboBox>
#include <QLocale>
using namespace std::chrono_literals;
ServicesView::ServicesView(OvhApi *api, QWidget *parent) :
QDialog(parent),
ui(new Ui::ServicesView),
api(api)
{
ui->setupUi(this);
ui->tableWidget->setColumnHidden(0, true);
ui->tableWidget->setColumnWidth(1, 250);
ui->tableWidget->setColumnWidth(5, 250);
ui->buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false);
// Load services in the event loop, "when possible"
QTimer::singleShot(0, this, &ServicesView::loadServices);
}
ServicesView::~ServicesView()
{
delete ui;
}
QCoro::Task<> ServicesView::loadServices()
{
ui->tableWidget->disconnect(SIGNAL(cellChanged(int, int)));
auto serviceIds = (co_await api->get("/services")).array();
int rowCount = serviceIds.count();
ui->tableWidget->setRowCount(serviceIds.count());
QLocale locale;
int i = 0;
for (const auto &&serviceIdJson: serviceIds) {
int serviceId = serviceIdJson.toInt();
auto serviceInfo = (co_await api->get(QString("/services/%1").arg(serviceId), 1h)).object();
qDebug() << serviceInfo;
if (!serviceInfo["parentServiceId"].isNull()) {
rowCount--;
ui->tableWidget->setRowCount(rowCount);
continue;
}
auto resourceInfo = serviceInfo["resource"].toObject();
auto billingInfo = serviceInfo["billing"].toObject();
auto currentLifecycle = billingInfo["lifecycle"].toObject()["current"].toObject();
auto engagement = billingInfo["engagement"].toObject();
int c = 0;
auto tableItem = new QTableWidgetItem(QString::number(serviceId));
tableItem->setFlags(Qt::ItemIsEnabled);
ui->tableWidget->setItem(i, c++, tableItem);
tableItem = new QTableWidgetItem(resourceInfo["displayName"].toString());
ui->tableWidget->setItem(i, c++, tableItem);
auto creationDate = QDateTime::fromString(currentLifecycle["creationDate"].toString(), Qt::ISODate);
tableItem = new QTableWidgetItem(locale.toString(creationDate.date(), QLocale::ShortFormat));
tableItem->setFlags(Qt::ItemIsEnabled);
ui->tableWidget->setItem(i, c++, tableItem);
auto expirationDate = QDateTime::fromString(billingInfo["expirationDate"].toString(), Qt::ISODate);
tableItem = new QTableWidgetItem(locale.toString(expirationDate.date(), QLocale::ShortFormat));
tableItem->setFlags(Qt::ItemIsEnabled);
ui->tableWidget->setItem(i, c++, tableItem);
if (!billingInfo["engagement"].isNull()) {
auto endDate = QDate::fromString(engagement["endDate"].toString(), Qt::ISODate);
tableItem = new QTableWidgetItem(locale.toString(endDate, QLocale::ShortFormat));
tableItem->setFlags(Qt::ItemIsEnabled);
ui->tableWidget->setItem(i, c++, tableItem);
auto endRule = engagement["endRule"].toObject();
tableItem = new QTableWidgetItem(endRule["strategy"].toString());
tableItem->setFlags(Qt::ItemIsEnabled);// TODO : editable with option list
ui->tableWidget->setItem(i, c, tableItem);
auto strategyCombobox = new QComboBox();
QStringList strategies;
for (const auto &&possibleStrategy: endRule["possibleStrategies"].toArray())
strategies.append(possibleStrategy.toString());
if (!strategies.contains(endRule["strategy"].toString()))
strategies.append(endRule["strategy"].toString());
strategyCombobox->addItems(strategies);
strategyCombobox->setCurrentIndex(strategies.indexOf(endRule["strategy"].toString()));
// Can't use the row id here, sorting will break it.
connect(strategyCombobox, &QComboBox::currentTextChanged, this, [this, serviceId] (const QString &newStrategy) {
qDebug() << "setting text to " << newStrategy << " for service " << serviceId;
// Find it back...
for (int r = 0 ; r < ui->tableWidget->rowCount() ; r++) {
if (ui->tableWidget->item(r, 0)->text().toInt() == serviceId) {
ui->tableWidget->item(r, 5)->setText(newStrategy);
}
}
});
ui->tableWidget->setCellWidget(i, c, strategyCombobox);
}
i++;
ui->tableWidget->resizeColumnsToContents();
}
connect(ui->tableWidget, &QTableWidget::cellChanged, this, &ServicesView::on_tableWidget_cellChanged);
}
void ServicesView::on_tableWidget_cellChanged(int row, [[maybe_unused]] int column)
{
int serviceId = ui->tableWidget->item(row, 0)->text().toInt();
if (!changedServices.contains(serviceId))
changedServices.append(serviceId);
qDebug() << "changed:" << changedServices;
ui->buttonBox->button(QDialogButtonBox::Apply)->setEnabled(true);
}
QCoro::Task<> ServicesView::on_buttonBox_clicked(QAbstractButton *button)
{
if (button == ui->buttonBox->button(QDialogButtonBox::Apply)) {
qDebug() << "APPLY for " << changedServices;
this->setEnabled(false);
for (int r = 0 ; r < ui->tableWidget->rowCount() ; r++) {
int serviceId = ui->tableWidget->item(r, 0)->text().toInt();
if (changedServices.contains(serviceId)) {
qDebug() << "Need to send changed values at row " << r;
QString newDisplayName = ui->tableWidget->item(r, 1)->text();
QString newStrategy = ui->tableWidget->item(r, 5)->text();
qDebug() << "New name ? " << newDisplayName;
qDebug() << "New strategy ? " << newStrategy;
auto currentInfo = (co_await api->get(QString("/services/%1").arg(serviceId))).object();
bool needToRefreshCache = false;
if (currentInfo["resource"].toObject()["displayName"].toString() != newDisplayName) {
// Build a PUT.
QJsonObject data {
{"displayName", newDisplayName}
};
co_await api->put(QString("/services/%1").arg(serviceId), QJsonDocument(data).toJson());
needToRefreshCache = true;
}
auto currentEngagement = currentInfo["billing"].toObject()["engagement"].toObject();
if (currentEngagement["endRule"].toObject()["strategy"] != newStrategy) {
QJsonObject data {
{"strategy", newStrategy}
};
co_await api->put(QString("/services/%1/billing/engagement/endRule").arg(serviceId), QJsonDocument(data).toJson());
needToRefreshCache = true;
}
if (needToRefreshCache)
co_await api->get(QString("/services/%1").arg(serviceId), 1h, true);
}
}
this->setEnabled(true);
this->accept();
}
}