ORE Studio 0.0.4
Loading...
Searching...
No Matches
ClientDatasetModel.hpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 *
3 * Copyright (C) 2025 Marco Craveiro <marco.craveiro@gmail.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it under
6 * the terms of the GNU General Public License as published by the Free Software
7 * Foundation; either version 3 of the License, or (at your option) any later
8 * version.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 * details.
14 *
15 * You should have received a copy of the GNU General Public License along with
16 * this program; if not, write to the Free Software Foundation, Inc., 51
17 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 *
19 */
20#ifndef ORES_QT_CLIENT_DATASET_MODEL_HPP
21#define ORES_QT_CLIENT_DATASET_MODEL_HPP
22
23#include <vector>
24#include <QSize>
25#include <QFutureWatcher>
26#include <QAbstractTableModel>
27#include "ores.qt/AbstractClientModel.hpp"
28#include <boost/uuid/uuid.hpp>
29#include <boost/uuid/uuid_io.hpp>
30#include "ores.qt/ClientManager.hpp"
31#include "ores.qt/ColumnMetadata.hpp"
32#include "ores.qt/RecencyPulseManager.hpp"
33#include "ores.qt/RecencyTracker.hpp"
34#include "ores.logging/make_logger.hpp"
35#include "ores.dq.api/domain/dataset.hpp"
36
37namespace ores::qt {
38
39class ClientDatasetModel final : public AbstractClientModel {
40 Q_OBJECT
41
42private:
43 inline static std::string_view logger_name =
44 "ores.qt.client_dataset_model";
45
46 [[nodiscard]] static auto& lg() {
47 using namespace ores::logging;
48 static auto instance = make_logger(logger_name);
49 return instance;
50 }
51
52public:
53 enum Column {
54 Name,
55 Code,
56 Catalog,
57 SubjectArea,
58 Domain,
59 Origin,
60 Nature,
61 Treatment,
62 SourceSystem,
63 AsOfDate,
64 Version,
65 ModifiedBy,
66 RecordedAt,
67 Tags,
68 ColumnCount
69 };
70
71 // Custom roles for Tags column data
72 static constexpr int OriginRole = Qt::UserRole + 100;
73 static constexpr int NatureRole = Qt::UserRole + 101;
74 static constexpr int TreatmentRole = Qt::UserRole + 102;
75
81 static constexpr std::size_t kColumnCount = std::size_t(ColumnCount);
82 static constexpr std::array<ColumnMetadata, kColumnCount> kColumns = {{
83 {
84 .column = Name,
85 .header = std::string_view("Name"),
87 .hidden_by_default = false,
88 .default_width = kColumnWidthAuto
89 },
90 {
91 .column = Code,
92 .header = std::string_view("Code"),
94 .hidden_by_default = false,
95 .default_width = kColumnWidthAuto
96 },
97 {
98 .column = Catalog,
99 .header = std::string_view("Catalog"),
101 .hidden_by_default = false,
102 .default_width = kColumnWidthAuto
103 },
104 {
105 .column = SubjectArea,
106 .header = std::string_view("Subject Area"),
108 .hidden_by_default = false,
109 .default_width = kColumnWidthAuto
110 },
111 {
112 .column = Domain,
113 .header = std::string_view("Domain"),
115 .hidden_by_default = false,
116 .default_width = kColumnWidthAuto
117 },
118 {
119 .column = Origin,
120 .header = std::string_view("Origin"),
122 .hidden_by_default = false,
123 .default_width = kColumnWidthAuto
124 },
125 {
126 .column = Nature,
127 .header = std::string_view("Nature"),
129 .hidden_by_default = false,
130 .default_width = kColumnWidthAuto
131 },
132 {
133 .column = Treatment,
134 .header = std::string_view("Treatment"),
136 .hidden_by_default = false,
137 .default_width = kColumnWidthAuto
138 },
139 {
140 .column = SourceSystem,
141 .header = std::string_view("Source System"),
143 .hidden_by_default = false,
144 .default_width = kColumnWidthAuto
145 },
146 {
147 .column = AsOfDate,
148 .header = std::string_view("As Of Date"),
150 .hidden_by_default = false,
151 .default_width = kColumnWidthAuto
152 },
153 {
154 .column = Version,
155 .header = std::string_view("Version"),
157 .hidden_by_default = false,
158 .default_width = 70
159 },
160 {
161 .column = ModifiedBy,
162 .header = std::string_view("Modified By"),
164 .hidden_by_default = false,
165 .default_width = kColumnWidthAuto
166 },
167 {
168 .column = RecordedAt,
169 .header = std::string_view("Recorded At"),
171 .hidden_by_default = false,
172 .default_width = kColumnWidthAuto
173 },
174 {
175 .column = Tags,
176 .header = std::string_view("Tags"),
178 .hidden_by_default = false,
179 .default_width = kColumnWidthAuto
180 }
181 }};
182
186 inline static const QSize kDefaultWindowSize = {900, 400};
187
191 static constexpr std::string_view kSettingsGroup = "DatasetMdiWindow";
195 static std::vector<column_style> const& columnStyles() {
196 static std::vector<column_style> const kStylesVector = []() {
197 std::vector<column_style> result;
198 result.reserve(kColumnCount);
199 for (std::size_t i = 0; i < kColumnCount; ++i)
200 result.push_back(kColumns[i].style);
201 return result;
202 }();
203 return kStylesVector;
204 }
205
209 static QVector<int> defaultHiddenColumns() {
210 static QVector<int> const result =
211 ::ores::qt::defaultHiddenColumns<kColumnCount>(kColumns);
212 return result;
213 }
214
215 explicit ClientDatasetModel(ClientManager* clientManager,
216 QObject* parent = nullptr);
217 ~ClientDatasetModel() override = default;
218
219 int rowCount(const QModelIndex& parent = QModelIndex()) const override;
220 int columnCount(const QModelIndex& parent = QModelIndex()) const override;
221 QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
222 QVariant headerData(int section, Qt::Orientation orientation,
223 int role = Qt::DisplayRole) const override;
224
225 void refresh();
226 const dq::domain::dataset* getDataset(int row) const;
227
228signals:
229
230private slots:
231 void onDatasetsLoaded();
232 void onPulseStateChanged(bool isOn);
233 void onPulsingComplete();
234
235private:
236 QVariant recency_foreground_color(const boost::uuids::uuid& id) const;
237
238 struct FetchResult {
239 bool success;
240 std::vector<dq::domain::dataset> datasets;
241 QString error_message;
242 QString error_details;
243 };
244
245 ClientManager* clientManager_;
246 std::vector<dq::domain::dataset> datasets_;
247 QFutureWatcher<FetchResult>* watcher_;
248 bool is_fetching_{false};
249
250 using DatasetKeyExtractor = std::string(*)(const dq::domain::dataset&);
251 RecencyTracker<dq::domain::dataset, DatasetKeyExtractor> recencyTracker_;
252 RecencyPulseManager* pulseManager_;
253};
254
255}
256
257#endif
Implements logging infrastructure for ORE Studio.
Definition boost_severity.hpp:28
Qt-based graphical user interface for ORE Studio.
Definition AccountController.hpp:32
QVector< int > defaultHiddenColumns(const std::array< ColumnMetadata, N > &columns)
Builds a QVector of hidden column indices from a metadata array.
Definition ColumnMetadata.hpp:99
constexpr int kColumnWidthAuto
Sentinel value for column default width meaning "auto-size to contents".
Definition ColumnMetadata.hpp:38
@ mono_center
Monospace, centered.
@ text_left
Proportional font, left-aligned (default).
@ mono_left
Monospace, left-aligned.
Represents a data quality dataset with lineage tracking.
Definition dataset.hpp:37