implemented version filtering by task tags

This commit is contained in:
Jakub Trllo 2025-06-12 18:39:07 +02:00
parent 5a4a888c22
commit 810b9cc573
2 changed files with 69 additions and 18 deletions

View file

@ -23,21 +23,16 @@ from .products_model import (
COMBO_VERSION_ID_ROLE = QtCore.Qt.UserRole + 1
COMBO_TASK_ID_ROLE = QtCore.Qt.UserRole + 2
COMBO_STATUS_NAME_ROLE = QtCore.Qt.UserRole + 3
COMBO_VERSION_TAGS_ROLE = QtCore.Qt.UserRole + 4
COMBO_TASK_TAGS_ROLE = QtCore.Qt.UserRole + 5
class ComboVersionsModel(QtGui.QStandardItemModel):
def __init__(self):
super().__init__()
self._items_by_id = {}
self._version_tags_by_version_id = {}
def get_version_tags(self, version_id: str) -> set[str]:
tags = self._version_tags_by_version_id.get(version_id)
if tags is None:
tags = set()
return tags
def update_versions(self, version_items):
def update_versions(self, version_items, task_tags_by_version_id):
version_ids = {
version_item.version_id
for version_item in version_items
@ -59,14 +54,17 @@ class ComboVersionsModel(QtGui.QStandardItemModel):
item = QtGui.QStandardItem(label)
item.setData(version_id, QtCore.Qt.UserRole)
self._items_by_id[version_id] = item
version_tags = set(version_item.tags)
task_tags = task_tags_by_version_id[version_id]
item.setData(version_id, COMBO_VERSION_ID_ROLE)
item.setData(version_item.status, COMBO_STATUS_NAME_ROLE)
item.setData(version_item.task_id, COMBO_TASK_ID_ROLE)
item.setData("|".join(version_tags), COMBO_VERSION_TAGS_ROLE)
item.setData("|".join(task_tags), COMBO_TASK_TAGS_ROLE)
version_tags_by_version_id[version_id] = set(version_item.tags)
if item.row() != idx:
root_item.insertRow(idx, item)
self._version_tags_by_version_id = version_tags_by_version_id
class ComboVersionsFilterModel(QtCore.QSortFilterProxyModel):
@ -75,6 +73,7 @@ class ComboVersionsFilterModel(QtCore.QSortFilterProxyModel):
self._status_filter = None
self._task_ids_filter = None
self._version_tags_filter = None
self._task_tags_filter = None
def filterAcceptsRow(self, row, parent):
index = None
@ -99,12 +98,28 @@ class ComboVersionsFilterModel(QtCore.QSortFilterProxyModel):
return False
if index is None:
index = self.sourceModel().index(row, 0, parent)
version_id = index.data(COMBO_VERSION_ID_ROLE)
model = self.sourceModel()
index = model.index(row, 0, parent)
version_tags_s = index.data(COMBO_TASK_TAGS_ROLE)
version_tags = set()
if version_tags_s:
version_tags = set(version_tags_s.split("|"))
model = self.sourceModel()
tags = model.get_version_tags(version_id)
if not tags & self._version_tags_filter:
if not version_tags & self._version_tags_filter:
return False
if self._task_tags_filter is not None:
if not self._task_tags_filter:
return False
if index is None:
model = self.sourceModel()
index = model.index(row, 0, parent)
task_tags_s = index.data(COMBO_TASK_TAGS_ROLE)
task_tags = set()
if task_tags_s:
task_tags = set(task_tags_s.split("|"))
if not (task_tags & self._task_tags_filter):
return False
return True
@ -115,6 +130,12 @@ class ComboVersionsFilterModel(QtCore.QSortFilterProxyModel):
self._task_ids_filter = task_ids
self.invalidateFilter()
def set_task_tags_filter(self, tags):
if self._task_tags_filter == tags:
return
self._task_tags_filter = tags
self.invalidateFilter()
def set_statuses_filter(self, status_names):
if self._status_filter == status_names:
return
@ -160,6 +181,13 @@ class VersionComboBox(QtWidgets.QComboBox):
if self.currentIndex() != 0:
self.setCurrentIndex(0)
def set_task_tags_filter(self, tags):
self._proxy_model.set_task_tags_filter(tags)
if self.count() == 0:
return
if self.currentIndex() != 0:
self.setCurrentIndex(0)
def set_statuses_filter(self, status_names):
self._proxy_model.set_statuses_filter(status_names)
if self.count() == 0:
@ -179,7 +207,12 @@ class VersionComboBox(QtWidgets.QComboBox):
return self.count() == 0
return False
def update_versions(self, version_items, current_version_id):
def update_versions(
self,
version_items,
current_version_id,
task_tags_by_version_id,
):
self.blockSignals(True)
version_items = list(version_items)
version_ids = [
@ -190,7 +223,9 @@ class VersionComboBox(QtWidgets.QComboBox):
current_version_id = version_ids[0]
self._current_id = current_version_id
self._versions_model.update_versions(version_items)
self._versions_model.update_versions(
version_items, task_tags_by_version_id
)
index = version_ids.index(current_version_id)
if self.currentIndex() != index:
@ -218,6 +253,7 @@ class VersionDelegate(QtWidgets.QStyledItemDelegate):
self._task_ids_filter = None
self._statuses_filter = None
self._version_tags_filter = None
self._task_tags_filter = None
def displayText(self, value, locale):
if not isinstance(value, numbers.Integral):
@ -243,6 +279,13 @@ class VersionDelegate(QtWidgets.QStyledItemDelegate):
for widget in self._editor_by_id.values():
widget.set_version_tags_filter(tags)
def set_task_tags_filter(self, tags):
if tags is not None:
tags = set(tags)
self._task_tags_filter = tags
for widget in self._editor_by_id.values():
widget.set_task_tags_filter(tags)
def paint(self, painter, option, index):
fg_color = index.data(QtCore.Qt.ForegroundRole)
if fg_color:
@ -254,7 +297,7 @@ class VersionDelegate(QtWidgets.QStyledItemDelegate):
fg_color = None
if not fg_color:
return super(VersionDelegate, self).paint(painter, option, index)
return super().paint(painter, option, index)
if option.widget:
style = option.widget.style()
@ -323,9 +366,16 @@ class VersionDelegate(QtWidgets.QStyledItemDelegate):
while hasattr(model, "sourceModel"):
model = model.sourceModel()
versions = model.get_version_items_by_product_id(product_id)
task_tags_by_version_id = {
version_item.version_id: model.get_task_tags_by_id(
version_item.task_id
)
for version_item in versions
}
editor.update_versions(versions, version_id)
editor.update_versions(versions, version_id, task_tags_by_version_id)
editor.set_tasks_filter(self._task_ids_filter)
editor.set_task_tags_filter(self._task_tags_filter)
editor.set_statuses_filter(self._statuses_filter)
def setModelData(self, editor, model, index):

View file

@ -322,6 +322,7 @@ class ProductsWidget(QtWidgets.QWidget):
self._products_proxy_model.set_version_tags_filter(version_tags)
def set_task_tags_filter(self, task_tags):
self._version_delegate.set_task_tags_filter(task_tags)
self._products_proxy_model.set_task_tags_filter(task_tags)
def set_product_type_filter(self, product_type_filters):